home *** CD-ROM | disk | FTP | other *** search
/ SGI Freeware 1999 August / SGI Freeware 1999 August.iso / dist / fw_xemacs.idb / usr / freeware / lib / xemacs-20.4 / lisp / w3 / w3.el.z / w3.el
Encoding:
Text File  |  1998-05-21  |  77.9 KB  |  2,389 lines

  1. ;;; w3.el --- Main functions for emacs-w3 on all platforms/versions
  2. ;; Author: wmperry
  3. ;; Created: 1997/12/24 20:09:55
  4. ;; Version: 1.151
  5. ;; Keywords: faces, help, comm, news, mail, processes, mouse, hypermedia
  6.  
  7. ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
  8. ;;; Copyright (c) 1993 - 1996 by William M. Perry <wmperry@cs.indiana.edu>
  9. ;;; Copyright (c) 1996, 1997 Free Software Foundation, Inc.
  10. ;;;
  11. ;;; This file is part of GNU Emacs.
  12. ;;;
  13. ;;; GNU Emacs is free software; you can redistribute it and/or modify
  14. ;;; it under the terms of the GNU General Public License as published by
  15. ;;; the Free Software Foundation; either version 2, or (at your option)
  16. ;;; any later version.
  17. ;;;
  18. ;;; GNU Emacs is distributed in the hope that it will be useful,
  19. ;;; but WITHOUT ANY WARRANTY; without even the implied warranty of
  20. ;;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  21. ;;; GNU General Public License for more details.
  22. ;;;
  23. ;;; You should have received a copy of the GNU General Public License
  24. ;;; along with GNU Emacs; see the file COPYING.  If not, write to the
  25. ;;; Free Software Foundation, Inc., 59 Temple Place - Suite 330,
  26. ;;; Boston, MA 02111-1307, USA.
  27. ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
  28.  
  29. ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
  30. ;;; This is a major mode for browsing documents written in Hypertext Markup ;;;
  31. ;;; Language (HTML).  These documents are typicallly part of the World Wide ;;;
  32. ;;; Web (WWW), a project to create a global information net in hypertext    ;;;
  33. ;;; format.                                                    ;;;
  34. ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
  35.  
  36. ;;; first start by making sure the load path is properly set.  This code
  37. ;;; is mostly taken from calc-2.02b
  38. ;;;
  39. ;;; this allows you to put the following in your .emacs file, instead of
  40. ;;; having to know what the load-path for the w3 files is.
  41. ;;;
  42. ;;;     (autoload 'w3 "w3/w3" "WWW Browser" t)
  43.  
  44. ;;; If w3 files exist on the load-path, we're all set.
  45. (let ((name (and (fboundp 'w3)
  46.          (eq (car-safe (symbol-function 'w3)) 'autoload)
  47.          (nth 1 (symbol-function 'w3))))
  48.       (p load-path))
  49.   (while (and p (not (file-exists-p
  50.               (expand-file-name "w3-vars.elc" (car p)))))
  51.     (setq p (cdr p)))
  52.   (or p
  53. ;;; If w3 is autoloaded using a path name, look there for w3 files.
  54. ;;; This works for both relative ("w3/w3.elc") and absolute paths.
  55.       (and name (file-name-directory name)
  56.        (let ((p2 load-path)
  57.          (name2 (concat (file-name-directory name)
  58.                 "w3-vars.elc")))
  59.          (while (and p2 (not (file-exists-p
  60.                   (expand-file-name name2 (car p2)))))
  61.            (setq p2 (cdr p2)))
  62.          (if p2
  63.          (setq load-path (nconc load-path
  64.                     (list
  65.                      (directory-file-name
  66.                       (file-name-directory
  67.                        (expand-file-name
  68.                         name (car p2)))))))))))
  69.   )
  70.  
  71.  
  72. (require 'w3-sysdp)
  73. (require 'mule-sysdp)
  74. (require 'widget)
  75.  
  76. (or (featurep 'efs)
  77.     (featurep 'efs-auto)
  78.     (condition-case ()
  79.     (require 'ange-ftp)
  80.       (error nil)))
  81.  
  82. (require 'cl)
  83. (require 'css)
  84. (require 'w3-vars)
  85. (eval-and-compile
  86.   (require 'w3-display))
  87.  
  88.  
  89. ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
  90. ;;; Code for printing out roman numerals
  91. ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
  92. (defun w3-decimal-to-roman (n)
  93.   ;; Convert from decimal to roman numerals
  94.   (let ((curmod 1000)
  95.     (str "")
  96.     (j 7)
  97.     i2 k curcnt)
  98.     (while (>= curmod 1)
  99.       (if (>= n curmod)
  100.       (progn
  101.         (setq curcnt (/ n curmod)
  102.           n (- n (* curcnt curmod)))
  103.         (if (= 4 (% curcnt 5))
  104.         (setq i2 (+ j (if (> curcnt 5) 1 0))
  105.               str (format "%s%c%c" str
  106.                   (aref w3-roman-characters (1- j))
  107.                   (aref w3-roman-characters i2)))
  108.           (progn
  109.         (if (>= curcnt 5)
  110.             (setq str (format "%s%c" str (aref w3-roman-characters j))
  111.               curcnt (- curcnt 5)))
  112.         (setq k 0)
  113.         (while (< k curcnt)
  114.           (setq str (format "%s%c" str
  115.                     (aref w3-roman-characters (1- j)))
  116.             k (1+ k)))))))
  117.       (setq curmod (/ curmod 10)
  118.         j (- j 2)))
  119.     str))
  120.  
  121. (defun w3-decimal-to-alpha (n)
  122.   ;; Convert from decimal to alphabetical (a, b, c, ..., aa, ab,...)
  123.   (cond
  124.    ((< n 1) (char-to-string ?Z))
  125.    ((<= n 26) (char-to-string (+ ?A (1- n))))
  126.    (t (concat (char-to-string (+ ?A (1- (/ n 27))))
  127.           (w3-decimal-to-alpha (% n 26))))))
  128.  
  129.  
  130. ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
  131. ;;; Functions to pass files off to external viewers
  132. ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
  133. (defun w3-start-viewer (fname cmd &optional view)
  134.   "Start a subprocess, named FNAME, executing CMD.
  135. If third arg VIEW is non-nil, show the output in a buffer when
  136. the subprocess exits."
  137.   (if view (save-excursion
  138.          (set-buffer (get-buffer-create view))
  139.          (erase-buffer)))
  140.   (start-process fname view shell-file-name shell-command-switch cmd))
  141.  
  142. (defun w3-viewer-filter (proc string)
  143.   ;; A process filter for asynchronous external viewers
  144.   (let ((buff (get-buffer-create (url-generate-new-buffer-name
  145.                   (symbol-name
  146.                    (read (nth 2 (process-command proc))))))))
  147.     (save-excursion
  148.       (set-buffer buff)
  149.       (erase-buffer)
  150.       (insert string)
  151.       (set-process-buffer proc buff)
  152.       (set-process-filter proc nil))))
  153.  
  154. (defun w3-viewer-sentinel (proc string)
  155.   ;; Delete any temp files left from a viewer process.
  156.   (let ((fname (process-name proc))
  157.     (buffr (process-buffer proc))
  158.     (status (process-exit-status proc)))
  159.     (if buffr
  160.     (w3-notify-when-ready buffr))
  161.     (and (/= 0 status)
  162.      (funcall url-confirmation-func
  163.           (format "Viewer for %s failed... save to disk? " fname))
  164.      (copy-file fname (read-file-name "Save as: ") t))
  165.     (if (and (file-exists-p fname)
  166.          (file-writable-p fname))
  167.     (delete-file fname)))
  168.   ;; FSF Emacs doesn't do this after calling a process-sentinel
  169.   (set-buffer (window-buffer (selected-window))))
  170.  
  171. (defun w3-notify-when-ready (buff)
  172.   "Notify the user when BUFF is ready.
  173. See the variable `w3-notify' for the different notification behaviors."
  174.   (if (stringp buff) (setq buff (get-buffer buff)))
  175.   (cond
  176.    ((null buff) nil)
  177.    ((eq w3-notify 'newframe)
  178.     ;; Since we run asynchronously, perhaps while Emacs is waiting for input,
  179.     ;; we must not leave a different buffer current.
  180.     ;; We can't rely on the editor command loop to reselect
  181.     ;; the selected window's buffer.
  182.     (save-excursion
  183.       (set-buffer buff)
  184.       (make-frame)))
  185.    ((eq w3-notify 'bully)
  186.     (pop-to-buffer buff)
  187.     (delete-other-windows))
  188.    ((eq w3-notify 'semibully)
  189.     (condition-case nil
  190.     (switch-to-buffer buff)
  191.       (error (message "W3 buffer %s is ready." (buffer-name buff)))))
  192.    ((eq w3-notify 'aggressive)
  193.     (pop-to-buffer buff))
  194.    ((eq w3-notify 'friendly)
  195.     (display-buffer buff 'not-this-window))
  196.    ((eq w3-notify 'polite)
  197.     (beep)
  198.     (message "W3 buffer %s is ready." (buffer-name buff)))
  199.    ((eq w3-notify 'quiet)
  200.     (message "W3 buffer %s is ready." (buffer-name buff)))
  201.    (t (message ""))))
  202.  
  203. (defun w3-pass-to-viewer ()
  204.   ;; Pass a w3 buffer to a viewer
  205.   (set-buffer url-working-buffer)
  206.   (let* ((info  url-current-mime-viewer)        ; All the MIME viewer info
  207.      (view (cdr-safe (assoc "viewer" info))) ; How to view this file
  208.      (url (url-view-url t))
  209.      (fmt  (cdr-safe (assoc "nametemplate" info)))) ; Template for name
  210.     (cond
  211.      (fmt nil)
  212.      ((cdr-safe (assoc "type" info))
  213.       (setq fmt (mm-type-to-file (cdr-safe (assoc "type" info))))
  214.       (if fmt
  215.       (setq fmt (concat "%s" (car fmt)))
  216.     (setq fmt (concat "%s" (url-file-extension
  217.                 (url-filename url-current-object)))))))
  218.     (if (null view)
  219.     (setq view 'indented-text-mode))
  220.     (cond
  221.      ((symbolp view)
  222.       (if (not (memq view '(w3-prepare-buffer w3-print w3-source
  223.                           w3-default-local-file
  224.                           mm-multipart-viewer)))
  225.       (let ((bufnam (url-generate-new-buffer-name
  226.              (file-name-nondirectory
  227.               (or (url-filename url-current-object)
  228.                   "Unknown")))))
  229.         (if (string= bufnam "")
  230.         (setq bufnam (url-generate-new-buffer-name
  231.                   (url-view-url t))))
  232.         (rename-buffer bufnam)
  233.         ;; Make the URL show in list-buffers output
  234.         (make-local-variable 'list-buffers-directory)
  235.         (setq list-buffers-directory (url-view-url t))
  236.         (set-buffer-modified-p nil)
  237.         (buffer-enable-undo)
  238.         (funcall view)
  239.         (w3-notify-when-ready bufnam))
  240.     (funcall view)))
  241.      ((stringp view)
  242.       (let ((fname (url-generate-unique-filename fmt))
  243.         (proc nil))
  244.     (if (url-file-directly-accessible-p (url-view-url t))
  245.         (make-symbolic-link (url-filename url-current-object) fname t)
  246.       (mule-write-region-no-coding-system (point-min) (point-max) fname))
  247.     (if (get-buffer url-working-buffer)
  248.         (kill-buffer url-working-buffer))
  249.     (setq view (mm-viewer-unescape view fname url))
  250.     (message "Passing to viewer %s " view)
  251.     (setq proc (w3-start-viewer fname view))
  252.     (set-process-filter proc 'w3-viewer-filter)
  253.     (set-process-sentinel proc 'w3-viewer-sentinel)))
  254.      ((listp view)
  255.       (set-buffer-modified-p nil)
  256.       (buffer-enable-undo)
  257.       (eval view))
  258.      (t
  259.       (message "Unknown viewer specified: %s" view)
  260.       (w3-notify-when-ready url-working-buffer)))))
  261.  
  262. (defun w3-save-binary-file ()
  263.   "Save a buffer to disk - this is used when `w3-dump-to-disk' is non-nil"
  264.   ;; Ok, this is truly fucked.  In XEmacs, if you use the mouse to select
  265.   ;; a URL that gets saved via this function, read-file-name will pop up a
  266.   ;; dialog box for file selection.  For some reason which buffer we are in
  267.   ;; gets royally screwed (even with save-excursions and the whole nine
  268.   ;; yards).  SO, we just keep the old buffer name around and away we go.
  269.   (let ((old-buff (current-buffer))
  270.     (file (read-file-name "Filename to save as: "
  271.                   (or mm-download-directory "~/")
  272.                   (url-remove-compressed-extensions
  273.                    (file-name-nondirectory (url-view-url t)))
  274.                   nil
  275.                   (url-remove-compressed-extensions
  276.                    (file-name-nondirectory (url-view-url t)))))
  277.     (require-final-newline nil))
  278.     (set-buffer old-buff)
  279.     (mule-write-region-no-coding-system (point-min) (point-max) file)
  280.     (kill-buffer (current-buffer))))
  281.  
  282. ;;;###autoload
  283. (defun w3-open-local (fname)
  284.   "Find a local file, and interpret it as a hypertext document.
  285. It will prompt for an existing file or directory, and retrieve it as a
  286. hypertext document."
  287.   (interactive "FLocal file: ")
  288.   (setq fname (expand-file-name fname))
  289.   (if (not w3-setup-done) (w3-do-setup))
  290.   (w3-fetch (concat "file:" fname)))
  291.  
  292. ;;;###autoload
  293. (defun w3-find-file (fname)
  294.   "Find a local file, and interpret it as a hypertext document.
  295. It will prompt for an existing file or directory, and retrieve it as a
  296. hypertext document."
  297.   (interactive "FLocal file: ")
  298.   (w3-open-local fname))
  299.  
  300. ;;;###autoload
  301. (defun w3-fetch-other-frame (&optional url)
  302.   "Attempt to follow the hypertext reference under point in a new frame.
  303. With prefix-arg P, ignore viewers and dump the link straight
  304. to disk."
  305.   (interactive (list (w3-read-url-with-default)))
  306.   (cond
  307.    ((and (fboundp 'make-frame)
  308.      (fboundp 'select-frame)
  309.      (not (eq (device-type) 'tty)))
  310.     (let ((frm (make-frame)))
  311.       (select-frame frm)
  312.       (delete-other-windows)
  313.       (w3-fetch url)))
  314.    (t (w3-fetch url))))
  315.  
  316. (defun w3-fetch-other-window (&optional url)
  317.   "Attempt to follow the hypertext reference under point in a new window.
  318. With prefix-arg P, ignore viewers and dump the link straight
  319. to disk."
  320.   (interactive (list (w3-read-url-with-default)))
  321.   (split-window)
  322.   (w3-fetch url))
  323.  
  324. ;; Ripped off from red gnus
  325. (defun w3-find-etc-directory (package &optional file)
  326.   "Go through the path and find the \".../etc/PACKAGE\" directory.
  327. If FILE, find the \".../etc/PACKAGE\" file instead."
  328.   (let ((path load-path)
  329.     dir result)
  330.     ;; We try to find the dir by looking at the load path,
  331.     ;; stripping away the last component and adding "etc/".
  332.     (while path
  333.       (if (and (car path)
  334.            (file-exists-p
  335.         (setq dir (concat
  336.                (file-name-directory
  337.                 (directory-file-name (car path)))
  338.                "etc/" package 
  339.                (if file "" "/"))))
  340.            (or file (file-directory-p dir)))
  341.       (setq result dir
  342.         path nil)
  343.     (setq path (cdr path))))
  344.     result))
  345.  
  346. (defun w3-url-completion-function (string predicate function)
  347.   (if (not w3-setup-done) (w3-do-setup))
  348.   (cond
  349.    ((eq function nil)
  350.     (let ((list nil))
  351.       (cl-maphash (function (lambda (key val)
  352.                   (setq list (cons (cons key val)
  353.                            list))))
  354.           url-global-history-hash-table)
  355.       (try-completion string (nreverse list) predicate)))
  356.    ((eq function t)
  357.     (let ((stub (concat "^" (regexp-quote string)))
  358.       (retval nil))
  359.       (cl-maphash
  360.        (function
  361.     (lambda (url time)
  362.       (if (string-match stub url)
  363.           (setq retval (cons url retval)))))
  364.        url-global-history-hash-table)
  365.       retval))
  366.    ((eq function 'lambda)
  367.     (and url-global-history-hash-table
  368.      (cl-gethash string url-global-history-hash-table)
  369.      t))
  370.    (t
  371.     (error "w3-url-completion-function very confused."))))
  372.  
  373. (defun w3-read-url-with-default ()
  374.   (url-do-setup)
  375.   (let* ((completion-ignore-case t)
  376.      (default
  377.        (cond
  378.         ((null w3-fetch-with-default) nil)
  379.         ((eq major-mode 'w3-mode)
  380.          (or (and current-prefix-arg (w3-view-this-url t))
  381.          (url-view-url t)))
  382.         ((url-get-url-at-point)
  383.          (url-get-url-at-point))
  384.         (t "http://www.")))
  385.      (url nil))
  386.     (setq url
  387.       (completing-read "URL: "  'w3-url-completion-function
  388.                nil nil default))
  389.     (if (string= url "")
  390.     (setq url (if (eq major-mode 'w3-mode)
  391.               (if (and current-prefix-arg (w3-view-this-url t))
  392.               (w3-view-this-url t)
  393.             (url-view-url t))
  394.             (url-get-url-at-point))))
  395.     url))
  396.  
  397. ;;;###autoload
  398. (defun w3-fetch (&optional url target)
  399.   "Retrieve a document over the World Wide Web.
  400. Defaults to URL of the current document, if any.
  401. With prefix argument, use the URL of the hyperlink under point instead."
  402.   (interactive (list (w3-read-url-with-default)))
  403.   (if (not w3-setup-done) (w3-do-setup))
  404.   (if (boundp 'w3-working-buffer)
  405.       (setq w3-working-buffer url-working-buffer))
  406.   (if (and (boundp 'command-line-args-left)
  407.        command-line-args-left
  408.        (string-match url-nonrelative-link (car command-line-args-left)))
  409.       (setq url (car command-line-args-left)
  410.         command-line-args-left (cdr command-line-args-left)))
  411.   (if (equal url "") (error "No document specified!"))
  412.   ;; legal use for relative URLs ?
  413.   (if (string-match "^www:[^/].*" url)
  414.       (setq url (concat (file-name-directory (url-filename
  415.                           url-current-object))
  416.              (substring url 4))))
  417.   ;; In the common case, this is probably cheaper than searching.
  418.   (while (= (string-to-char url) ? )
  419.     (setq url (substring url 1)))
  420.   (or target (setq target w3-base-target))
  421.   (if (stringp target)
  422.       (setq target (intern (downcase target))))
  423.   (and target
  424.        (let ((window-distance (cdr-safe (assq target w3-target-window-distances))))
  425.      (if (numberp window-distance)
  426.          (other-window window-distance)
  427.        (case target
  428.          ((_blank external)
  429.           (w3-fetch-other-frame url))
  430.          (_top
  431.           (delete-other-windows))
  432.          (otherwise
  433.           (message "target %S not found." target))))))
  434.   (cond
  435.    ((= (string-to-char url) ?#)
  436.     (w3-relative-link url))
  437.    ((or (and (interactive-p) current-prefix-arg) w3-dump-to-disk)
  438.     (w3-download-url url))
  439.    (t
  440.     (let ((x (url-view-url t))
  441.       (lastbuf (current-buffer))
  442.       (buf (url-buffer-visiting url)))
  443.       (if (or (not buf)
  444.           (cond
  445.            ((not (equal (downcase (or url-request-method "GET")) "get")) t)
  446.            ((memq w3-reuse-buffers '(no never reload)) t)
  447.            ((memq w3-reuse-buffers '(yes reuse always)) nil)
  448.            (t
  449.         (if (and w3-reuse-buffers (not (eq w3-reuse-buffers 'ask)))
  450.             (progn
  451.               (ding)
  452.               (message
  453.                "Warning: Invalid value for variable w3-reuse-buffers: %s"
  454.                (prin1-to-string w3-reuse-buffers))
  455.               (sit-for 2)))
  456.         (not (funcall url-confirmation-func
  457.                   (format "Reuse URL in buffer %s? "
  458.                       (buffer-name buf)))))))
  459.       (let* ((status (url-retrieve url))
  460.          (cached (car status))
  461.          (url-working-buffer (cdr status)))
  462.         (if w3-track-last-buffer
  463.         (setq w3-last-buffer (get-buffer url-working-buffer)))
  464.         (if (get-buffer url-working-buffer)
  465.         (cond
  466.          ((and url-be-asynchronous (not cached))
  467.           (save-excursion
  468.             (set-buffer url-working-buffer)
  469.             (w3-history-push x (url-view-url t))
  470.             (setq w3-current-last-buffer lastbuf)))
  471.          (t
  472.           (w3-history-push x url)
  473.           (w3-sentinel lastbuf)))))
  474.     (if w3-track-last-buffer
  475.         (setq w3-last-buffer buf))
  476.     (let ((w3-notify (if (memq w3-notify '(newframe bully 
  477.                            semibully aggressive))
  478.                  w3-notify
  479.                'aggressive)))
  480.       (w3-notify-when-ready buf))
  481.     (if (string-match "#\\(.*\\)" url)
  482.         (progn
  483.           (push-mark (point) t)
  484.           (w3-find-specific-link (url-match url 1))))
  485.     (or (w3-maybe-fetch-frames)
  486.         (message "Reusing URL.  To reload, type %s."
  487.              (substitute-command-keys "\\[w3-reload-document]"))))))))
  488.  
  489.  
  490. ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
  491. ;;; History for forward/back buttons
  492. ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
  493. (defvar w3-history-stack nil
  494.   "History stack viewing history.
  495. This is an assoc list, with the oldest items first.
  496. Each element is a cons cell of (url . timeobj), where URL
  497. is the normalized URL (default ports removed, etc), and TIMEOBJ is
  498. a standard Emacs time.  See the `current-time' function documentation
  499. for information on this format.")
  500.  
  501. (defun w3-history-find-url-internal (url)
  502.   "Search in the history list for URL.
  503. Returns a cons cell, where the car is the 'back' node, and
  504. the cdr is the 'next' node."
  505.   (let* ((node (assoc url w3-history-stack))
  506.      (next (cadr (memq node w3-history-stack)))
  507.      (last nil)
  508.      (temp nil)
  509.      (todo w3-history-stack))
  510.     ;; Last node is a little harder to find without using back links
  511.     (while (and (not last) todo)
  512.       (if (string= (caar todo) url)
  513.       (setq last (or temp 'none))
  514.     (setq temp (pop todo))))
  515.     (cons (if (not (symbolp last)) last)
  516.       next)))
  517.  
  518. (defun w3-history-forward ()
  519.   "Go forward in the history from this page"
  520.   (interactive)
  521.   (let ((next (cadr (w3-history-find-url-internal (url-view-url t))))
  522.     (w3-reuse-buffers 'yes))
  523.     (if next
  524.     (w3-fetch next))))
  525.  
  526. (defun w3-history-backward ()
  527.   "Go backward in the history from this page"
  528.   (interactive)
  529.   (let ((last (caar (w3-history-find-url-internal (url-view-url t))))
  530.     (w3-reuse-buffers 'yes))
  531.     (if last
  532.     (w3-fetch last))))
  533.  
  534. (defun w3-history-push (referer url)
  535.   "REFERER is the url we followed this link from.  URL is the link we got to."
  536.   (if (not referer)
  537.       (setq w3-history-stack (list (cons url (current-time))))
  538.     (let ((node (memq (assoc referer w3-history-stack) w3-history-stack)))
  539.       (if node
  540.       (setcdr node (list (cons url (current-time))))
  541.     (setq w3-history-stack (append w3-history-stack
  542.                        (list
  543.                     (cons url (current-time)))))))))
  544.  
  545. (defalias 'w3-add-urls-to-history 'w3-history-push)
  546. (defalias 'w3-backward-in-history 'w3-history-backward)
  547. (defalias 'w3-forward-in-history 'w3-history-forward)
  548.  
  549.  
  550. ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
  551. ;;; Miscellaneous functions
  552. ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
  553. (defun w3-describe-entities ()
  554.   "Show an DTD fragment listing all the entities currently defined."
  555.   (interactive)
  556.   (switch-to-buffer (get-buffer-create "W3 Entities"))
  557.   (let ((buffer-file-name (concat (make-temp-name "entities") ".dtd")))
  558.     (set-auto-mode))
  559.   (erase-buffer)
  560.   (let (entity)
  561.     (mapatoms
  562.      (function
  563.       (lambda (x)
  564.     (setq entity (get x 'html-entity-expansion))
  565.     (if entity
  566.         (insert (format "<!entity %s %s \"%s\">\n" x (car entity)
  567.                 (cdr entity))))))))
  568.   (goto-char (point-min)))
  569.  
  570. (defun w3-executable-exists-in-path (exec &optional path)
  571.   (let ((paths (if (consp path)
  572.            path
  573.          (mm-string-to-tokens (or path
  574.                       (getenv "PATH")
  575.                       (concat
  576.                        "/usr/bin:/bin:/usr/local/bin:"
  577.                        "/usr/bin/X11:"
  578.                        (expand-file-name "~/bin"))) ?:)))
  579.     (done nil))
  580.     (while (and paths (not done))
  581.       (if (file-exists-p (expand-file-name exec (car paths)))
  582.       (setq done t))
  583.       (setq paths (cdr paths)))
  584.     done))
  585.  
  586. (defun w3-document-information (&optional buff)
  587.   "Display information on the document in buffer BUFF"
  588.   (interactive)
  589.   (if (interactive-p)
  590.       (let ((w3-notify 'friendly))
  591.     (if (get-buffer "Document Information")
  592.         (kill-buffer (get-buffer "Document Information")))
  593.     (w3-fetch "about:document"))
  594.     (setq buff (or buff (current-buffer)))
  595.     (save-excursion
  596.       (set-buffer buff)
  597.       (let* ((url (url-view-url t))
  598.          (cur-links w3-current-links)
  599.          (title (buffer-name))
  600.          (case-fold-search t)
  601.          (possible-lastmod (save-excursion
  602.                  (goto-char (point-min))
  603.                  (if (re-search-forward "^Last modified:\\(.*\\)" nil t)
  604.                      (buffer-substring (match-beginning 1)
  605.                                (match-end 1)))))
  606.          (attributes (url-file-attributes url))
  607.          (lastmod (or (cdr-safe (assoc "last-modified"
  608.                        url-current-mime-headers))
  609.               (nth 5 attributes)))
  610.          (hdrs url-current-mime-headers)
  611.          (size (or (cdr (assoc "content-length" url-current-mime-headers))
  612.                (buffer-size)))
  613.          (info w3-current-metainfo))
  614.     (set-buffer (get-buffer-create url-working-buffer))
  615.     (setq url-current-can-be-cached nil)
  616.     (erase-buffer)
  617.     (cond
  618.      ((stringp lastmod) nil)
  619.      ((equal '(0 . 0) lastmod) (setq lastmod possible-lastmod))
  620.      ((consp lastmod) (setq lastmod (current-time-string lastmod)))
  621.      (t (setq lastmod possible-lastmod)))
  622.     (setq url-current-mime-type "text/html")
  623.     (insert "<html>\n"
  624.         " <head>\n"
  625.         "  <title>Document Information</title>\n"
  626.         " </head>\n"
  627.         " <body\n"
  628.         "  <table border>\n"
  629.         "   <tr><th colspan=2>Document Information</th></tr>\n"
  630.         "   <tr><td>Title:</td><td>" title "</td></tr>\n"
  631.         "   <tr><td>Location:</td><td>" url "</td></tr>\n"
  632.         "   <tr><td>Size:</td><td>" (url-pretty-length
  633.                          (if (stringp size)
  634.                          (string-to-int size)
  635.                            size)) "</td></tr>\n"
  636.         "   <tr><td>Last Modified:</td><td>" (or lastmod "None Given")
  637.         "</td></tr>\n")
  638.     (if hdrs
  639.         (let* ((maxlength (car (sort (mapcar (function (lambda (x)
  640.                                  (length (car x))))
  641.                          hdrs)
  642.                      '>)))
  643.            (fmtstring (format "   <tr><td align=right>%%%ds:</td><td>%%s</td></tr>" maxlength)))
  644.           (insert "  <tr><th colspan=2>MetaInformation</th></tr>\n"
  645.               (mapconcat
  646.                (function
  647.             (lambda (x)
  648.               (if (/= (length (car x)) 0)
  649.                   (format fmtstring
  650.                       (url-insert-entities-in-string
  651.                        (capitalize (car x)))
  652.                       (url-insert-entities-in-string
  653.                        (if (numberp (cdr x))
  654.                        (int-to-string (cdr x))
  655.                      (cdr x)))))))
  656.                (sort hdrs
  657.                  (function
  658.                   (lambda (x y) (string-lessp (car x) (car y)))))
  659.                "\n"))))
  660.  
  661.     ;; FIXME!!! Need to reimplement showing rel/rev links for the new
  662.     ;; storage format.
  663.     
  664.     (if info
  665.         (let* ((maxlength (car (sort (mapcar (function (lambda (x)
  666.                                  (length (car x))))
  667.                          info)
  668.                      '>)))
  669.            (fmtstring (format "   <tr><td>%%%ds:</td><td>%%s</td></tr>" maxlength)))
  670.           (insert "   <tr><th colspan=2>Miscellaneous Variables</th></tr>\n")
  671.           (while info
  672.         (if (and (caar info) (cdar info))
  673.             (insert (format fmtstring
  674.                     (url-insert-entities-in-string
  675.                      (capitalize (caar info)))
  676.                     (url-insert-entities-in-string
  677.                      (cdar info))) "\n"))
  678.         (setq info (cdr info))
  679.         )
  680.           )
  681.       )
  682.     (insert "  </table>\n"
  683.         " </body>\n"
  684.         "</html>\n")))))
  685.  
  686. (defun w3-truncate-menu-item (string)
  687.   (if (<= (length string) w3-max-menu-width)
  688.       string
  689.     (concat (substring string 0 w3-max-menu-width) "$")))
  690.  
  691. (defun w3-insert-formatted-url (p)
  692.   "Insert a formatted url into a buffer.  With prefix arg, insert the url
  693. under point."
  694.   (interactive "P")
  695.   (let (buff str)
  696.     (cond
  697.      (p
  698.       (setq p (widget-at (point)))
  699.       (or p (error "No url under point"))
  700.       (setq str (format "<a href=\"%s\">%s</a>" (widget-get p :href)
  701.             (read-string "Link text: "
  702.                      (buffer-substring
  703.                                       (widget-get p :from)
  704.                                       (widget-get p :to))))))
  705.      (t
  706.       (setq str (format "<a href=\"%s\">%s</a>" (url-view-url t)
  707.             (read-string "Link text: " (buffer-name))))))
  708.     (setq buff (read-buffer "Insert into buffer: " nil t))
  709.     (if buff
  710.     (save-excursion
  711.       (set-buffer buff)
  712.       (insert str))
  713.       (message "Cancelled."))))
  714.  
  715. (defun w3-first-n-items (l n)
  716.   "Return the first N items from list L"
  717.   (let ((x 0)
  718.     y)
  719.     (if (> n (length l))
  720.     (setq y l)
  721.       (while (< x n)
  722.     (setq y (nconc y (list (nth x l)))
  723.           x (1+ x))))
  724.     y))
  725.  
  726. (defun w3-widget-button-press ()
  727.   (interactive)
  728.   (if (widget-at (point))
  729.       (widget-button-press (point))))
  730.  
  731. (defun w3-widget-button-click (e)
  732.   (interactive "@e")
  733.   (cond
  734.    ((and (event-point e)
  735.      (widget-at (event-point e)))
  736.     (widget-button-click e))
  737.    ((and (fboundp 'event-glyph)
  738.      (event-glyph e)
  739.      (glyph-property (event-glyph e) 'widget))
  740.     (widget-button-click e))))
  741.    
  742. (defun w3-breakup-menu (menu-desc max-len)
  743.   (if (> (length menu-desc) max-len)
  744.       (cons (cons "More..." (w3-first-n-items menu-desc max-len))
  745.         (w3-breakup-menu (nthcdr max-len menu-desc) max-len))
  746.     menu-desc))
  747.  
  748. ;;;###autoload
  749. (defun w3-maybe-follow-link-mouse (e)
  750.   "Maybe follow a hypertext link under point.
  751. If there is no link under point, this will try using
  752. url-get-url-at-point"
  753.   (interactive "e")
  754.   (save-excursion
  755.     (mouse-set-point e)
  756.     (w3-maybe-follow-link)))
  757.  
  758. ;;;###autoload
  759. (defun w3-maybe-follow-link ()
  760.   "Maybe follow a hypertext link under point.
  761. If there is no link under point, this will try using
  762. url-get-url-at-point"
  763.   (interactive)
  764.   (require 'w3)
  765.   (if (not w3-setup-done) (w3-do-setup))
  766.   (let* ((widget (widget-at (point)))
  767.          (url1 (and widget (widget-get widget :href)))
  768.          (url2 (url-get-url-at-point)))
  769.     (cond
  770.       (url1 (widget-button-press))
  771.       ((and url2 (string-match url-nonrelative-link url2)) (w3-fetch url2))
  772.       (t (message "No URL could be found!")))))
  773.  
  774. ;;;###autoload
  775. (defun w3-follow-url-at-point-other-frame (&optional pt)
  776.   "Follow the URL under PT, defaults to link under (point)"
  777.   (interactive "d")
  778.   (let ((url (url-get-url-at-point pt)))
  779.     (and url (w3-fetch-other-frame url))))
  780.  
  781. ;;;###autoload
  782. (defun w3-follow-url-at-point (&optional pt)
  783.   "Follow the URL under PT, defaults to link under (point)"
  784.   (interactive "d")
  785.   (let ((url (url-get-url-at-point pt)))
  786.     (and url (w3-fetch url))))
  787.  
  788. (defun w3-fix-spaces (x)
  789.   "Remove spaces/tabs at the beginning of a string,
  790. and convert newlines into spaces."
  791.   (url-convert-newlines-to-spaces
  792.    (url-strip-leading-spaces
  793.     (url-eat-trailing-space x))))
  794.  
  795. (defun w3-reload-all-files ()
  796.   "Reload all w3 files"
  797.   (interactive)
  798.   (setq w3-setup-done nil
  799.     url-setup-done nil
  800.     w3-hotlist nil
  801.     url-mime-accept-string nil)
  802.   (let ((x '(w3 base64 css mule-sysdp w3-e19 mm url w3-xemac
  803.         w3-e20 dsssl dsssl-flow font images ssl url-auth
  804.         url-cache url-cookie url-file url-gopher url-gw
  805.         url-http url-mail url-misc url-news url-ns url-parse
  806.         url-vars w3-about w3-cus w3-display w3-e20 w3-elisp
  807.         w3-emulate w3-forms w3-hot w3-imap w3-jscript
  808.         w3-keyword w3-latex w3-menu w3-mouse w3-parse
  809.         w3-prefs w3-print w3-props w3-script w3-speak w3-style
  810.         w3-sysdp w3-toolbar w3-vars w3-widget w3-xemac w3
  811.         w3-toolbar font)))
  812.     (while x
  813.       (setq features (delq (car x) features)
  814.         x (cdr x)))
  815.     (require 'w3))
  816.   (mapatoms (function
  817.          (lambda (sym)
  818.            (if (or (string-match "^w3-" (symbol-name sym))
  819.                (string-match "^url-" (symbol-name sym))
  820.                (string-match "^ssl-" (symbol-name sym))
  821.                (string-match "^base64-" (symbol-name sym))
  822.                (string-match "^dsssl-" (symbol-name sym))
  823.                (string-match "^mm-" (symbol-name sym)))
  824.            (progn
  825.              (fmakunbound sym)
  826.              (makunbound sym))))))
  827.   (require 'w3))
  828.  
  829. (defun w3-source-document-at-point ()
  830.   "View source to the document pointed at by link under point"
  831.   (interactive)
  832.   (w3-source-document t))
  833.  
  834. (defun w3-source-document (under)
  835.   "View this document's source"
  836.   (interactive "P")
  837.   (let* ((url (if under (w3-view-this-url) (url-view-url t)))
  838.      (src
  839.       (cond
  840.        ((null url)
  841.         (error "No URL found!"))
  842.        ((and under (null url)) (error "No link at point!"))
  843.        ((and (not under) (equal url-current-mime-type "text/plain"))
  844.         (buffer-string))
  845.        ((and (not under) w3-current-source) w3-current-source)
  846.        (t
  847.         (prog2
  848.         (url-retrieve url)
  849.         (buffer-string)
  850.           (kill-buffer (current-buffer))))))
  851.      (tmp (url-generate-new-buffer-name url)))
  852.     (if (and url (get-buffer url))
  853.     (cond
  854.      ((memq w3-reuse-buffers '(no never reload))
  855.       (kill-buffer url))
  856.      ((memq w3-reuse-buffers '(yes reuse always))
  857.       (w3-notify-when-ready (get-buffer url))
  858.       (setq url nil))
  859.      ((funcall url-confirmation-func
  860.            (concat "Source for " url " found, reuse? "))
  861.       (w3-notify-when-ready (get-buffer url)))))
  862.     (if (not url) nil
  863.       (set-buffer (get-buffer-create tmp))
  864.       (insert src)
  865.       (put-text-property (point-min) (point-max) 'w3-base url)
  866.       (goto-char (point-min))
  867.       (setq buffer-file-truename url
  868.         buffer-file-name url)
  869.       ;; Null filename bugs `set-auto-mode' in Mule ...
  870.       (condition-case ()
  871.        (set-auto-mode)
  872.     (error nil))
  873.       (setq buffer-file-truename nil
  874.         buffer-file-name nil)
  875.       (buffer-enable-undo)
  876.       (set-buffer-modified-p nil)
  877.       (w3-notify-when-ready (get-buffer tmp))))
  878.   (run-hooks 'w3-source-file-hook))
  879.  
  880. (defun w3-mail-document-under-point ()
  881.   "Mail the document pointed to by the hyperlink under point."
  882.   (interactive)
  883.   (w3-mail-current-document t))
  884.  
  885. (defun w3-mail-current-document (under &optional format)
  886.   "Mail the current-document to someone"
  887.   (interactive "P")
  888.   (let* ((completion-ignore-case t)
  889.      (format (or format
  890.              (completing-read
  891.               "Format: "
  892.               '(("HTML Source")
  893.             ("Formatted Text")
  894.             ("PostScript")
  895.             ("LaTeX Source")
  896.             )
  897.           nil t)))
  898.      (case-fold-search t)
  899.      (url (cond
  900.            ((stringp under) under)
  901.            (under (w3-view-this-url t))
  902.            (t (url-view-url t))))
  903.      (content-type "text/plain; charset=iso-8859-1")
  904.      (str
  905.       (save-excursion
  906.         (cond
  907.          ((and (equal "HTML Source" format) under)
  908.           (setq content-type "text/html; charset=iso-8859-1")
  909.           (let ((url-source t))
  910.         (url-retrieve url)))
  911.          ((equal "HTML Source" format)
  912.           (setq content-type "text/html; charset=iso-8859-1")
  913.           (if w3-current-source
  914.           (let ((x w3-current-source))
  915.             (set-buffer (get-buffer-create url-working-buffer))
  916.             (erase-buffer)
  917.             (insert x))
  918.         (url-retrieve url)))
  919.          ((and under (equal "PostScript" format))
  920.           (setq content-type "application/postscript")
  921.           (w3-fetch url)
  922.           (require 'ps-print)
  923.           (let ((ps-spool-buffer-name " *w3-temp*"))
  924.         (if (get-buffer ps-spool-buffer-name)
  925.             (kill-buffer ps-spool-buffer-name))
  926.         (ps-spool-buffer-with-faces)
  927.         (set-buffer ps-spool-buffer-name)))
  928.          ((equal "PostScript" format)
  929.           (require 'ps-print)
  930.           (let ((ps-spool-buffer-name " *w3-temp*"))
  931.         (if (get-buffer ps-spool-buffer-name)
  932.             (kill-buffer ps-spool-buffer-name))
  933.         (setq content-type "application/postscript")
  934.         (ps-spool-buffer-with-faces)
  935.         (set-buffer ps-spool-buffer-name)))
  936.          ((and under (equal "Formatted Text" format))
  937.           (setq content-type "text/plain; charset=iso-8859-1")
  938.           (w3-fetch url))
  939.          ((equal "Formatted Text" format)
  940.           (setq content-type "text/plain; charset=iso-8859-1"))
  941.          ((and under (equal "LaTeX Source" format))
  942.           (let ((old-asynch (default-value 'url-be-asynchronous)))
  943.         (setq content-type "application/x-latex; charset=iso-8859-1")
  944.         (unwind-protect
  945.             (progn
  946.               (setq-default url-be-asynchronous nil)
  947.               (url-retrieve url))
  948.           (setq-default url-be-asynchronous old-asynch))
  949.         (w3-parse-tree-to-latex (w3-parse-buffer (current-buffer))
  950.                     url)))
  951.          ((equal "LaTeX Source" format)
  952.           (setq content-type "application/x-latex; charset=iso-8859-1")
  953.           (w3-parse-tree-to-latex w3-current-parse url)))
  954.         (buffer-string))))
  955.     (funcall url-mail-command)
  956.     (mail-subject)
  957.     (if (and (boundp 'mime/editor-mode-flag) mime/editor-mode-flag)
  958.         (insert format " from <URL: " url ">")
  959.       (insert format " from <URL: " url ">\n"
  960.               "Mime-Version: 1.0\n"
  961.               "Content-transfer-encoding: 8bit\n"
  962.               "Content-type: " content-type))
  963.     (re-search-forward mail-header-separator nil)
  964.     (forward-char 1)
  965.     (if (and (boundp 'mime/editor-mode-flag) mime/editor-mode-flag)
  966.         (insert (format mime-tag-format content-type) "\n"))
  967.     (save-excursion
  968.       (insert str))
  969.     (cond ((equal "HTML Source" format)
  970.            (if (or (search-forward "<head>" nil t)
  971.            (search-forward "<html>" nil t))
  972.            (insert "\n"))
  973.            (insert (format "<base href=\"%s\">" url))))
  974.     (mail-to)))
  975.  
  976. (defun w3-internal-use-history (hist-item)
  977.   ;; Go to the link in the history
  978.   (let ((url (nth 0 hist-item))
  979.     (buf (nth 1 hist-item))
  980.     (pnt (nth 2 hist-item)))
  981.     (cond
  982.      ((null buf)            ; Find a buffer with same url
  983.       (let ((x (buffer-list))
  984.         (found nil))
  985.     (while (and x (not found))
  986.       (save-excursion
  987.         (set-buffer (car x))
  988.         (setq found (string= (url-view-url t) url))
  989.         (if (not found) (setq x (cdr x)))))
  990.     (cond
  991.      (found
  992.       (switch-to-buffer (car x))
  993.       (if (number-or-marker-p pnt) (goto-char pnt)))
  994.      (t
  995.       (w3-fetch url)))))
  996.      ((buffer-name buf)            ; Reuse the old buffer if possible
  997.       (switch-to-buffer buf)
  998.       (if (number-or-marker-p pnt) (goto-char pnt))
  999.       (if (and url (= ?# (string-to-char url)))    ; Destination link
  1000.       (progn
  1001.         (goto-char (point-min))
  1002.         (w3-find-specific-link (substring url 1 nil)))))
  1003.      (url (url-maybe-relative url))        ; Get the link
  1004.      (t (message "Couldn't understand whats in the history.")))))
  1005.  
  1006. (defun w3-relative-link (url)
  1007.   (if (equal "#" (substring url 0 1))
  1008.       (progn
  1009.     (push-mark (point) t)
  1010.     (goto-char (point-min))
  1011.     (w3-find-specific-link (substring url 1 nil)))
  1012.     (w3-fetch (url-expand-file-name url))))
  1013.  
  1014. (defun w3-maybe-eval ()
  1015.   ;; Maybe evaluate a buffer of emacs lisp code
  1016.   (if (funcall url-confirmation-func "This is emacs-lisp code, evaluate it?")
  1017.       (eval-buffer (current-buffer))
  1018.     (emacs-lisp-mode)))
  1019.  
  1020. (defun w3-build-continuation ()
  1021.   ;; Build a series of functions to be run on this file
  1022.   (save-excursion
  1023.     (set-buffer url-working-buffer)
  1024.     (let ((cont w3-default-continuation)
  1025.       (extn (url-file-extension
  1026.          (url-filename url-current-object))))
  1027.       (if (assoc extn url-uncompressor-alist)
  1028.       (setq extn (url-file-extension
  1029.               (substring (url-filename url-current-object)
  1030.                  0 (- (length extn))))))
  1031.       (if w3-source
  1032.       (setq url-current-mime-viewer '(("viewer" . w3-source))))
  1033.       (if (not url-current-mime-viewer)
  1034.       (setq url-current-mime-viewer
  1035.         (mm-mime-info (or url-current-mime-type
  1036.                   (mm-extension-to-mime extn)) nil 5)))
  1037.       (if url-current-mime-viewer
  1038.       (setq cont (append cont '(w3-pass-to-viewer)))
  1039.     (setq cont (append cont (list 'w3-prepare-buffer))))
  1040.       cont)))
  1041.  
  1042. (defun w3-use-links ()
  1043.   "Select one of the <LINK> tags from this document and fetch it."
  1044.   (interactive)
  1045.   (and (not w3-current-links)
  1046.        (error "No links defined for this document."))
  1047.   (w3-fetch "about:document"))
  1048.  
  1049. (defun w3-find-this-file ()
  1050.   "Do a find-file on the currently viewed html document if it is a file: or
  1051. ftp: reference"
  1052.   (interactive)
  1053.   (or url-current-object
  1054.       (error "Not a URL-based buffer"))
  1055.   (let ((type (url-type url-current-object)))
  1056.     (cond
  1057.      ((equal type "file")
  1058.       (find-file (url-filename url-current-object)))
  1059.      ((equal type "ftp")
  1060.       (find-file
  1061.        (format "/%s@%s:%s"
  1062.            (url-user url-current-object)
  1063.            (url-host url-current-object)
  1064.            (url-filename url-current-object))))
  1065.      (t (message "Sorry, I can't get that file so you can alter it.")))))
  1066.  
  1067. (defun w3-insert-this-url (pref-arg)
  1068.   "Insert the current url in another buffer, with prefix ARG,
  1069. insert URL under point"
  1070.   (interactive "P")
  1071.   (let ((thebuf (get-buffer (read-buffer "Insert into buffer: ")))
  1072.     (oldbuf (current-buffer))
  1073.     (url (if pref-arg (w3-view-this-url t) (url-view-url t))))
  1074.     (if (and url (not (equal "Not on a link!" url)))
  1075.     (progn
  1076.       (set-buffer thebuf)
  1077.       (insert url)
  1078.       (set-buffer oldbuf))
  1079.       (message "Not on a link!"))))
  1080.  
  1081. (defun w3-show-hotlist ()
  1082.   "View the hotlist in hypertext form"
  1083.   (interactive)
  1084.   (if (not w3-setup-done) (w3-do-setup))
  1085.   (if (not w3-hotlist)
  1086.       (error "Sorry, no hotlist is in memory.")
  1087.     (let ((x (url-buffer-visiting "www:/auto/hotlist")))
  1088.       (while x
  1089.     (kill-buffer x)
  1090.     (setq x (url-buffer-visiting "www:/auto/hotlist"))))
  1091.     (w3-fetch "www://auto/hotlist")))
  1092.  
  1093. (defun url-maybe-relative (url)
  1094.   "Take a url and either fetch it, or resolve relative refs, then fetch it"
  1095.   (cond
  1096.    ((not
  1097.      (string-match url-nonrelative-link url))
  1098.     (w3-relative-link url))
  1099.    (t (w3-fetch url))))
  1100.  
  1101. (defun w3-in-assoc (elt list)
  1102.   "Check to see if ELT matches any of the regexps in the car elements of LIST"
  1103.   (let (rslt)
  1104.     (while (and list (not rslt))
  1105.       (and (car (car list))
  1106.        (stringp (car (car list)))
  1107.        (not (string= (car (car list)) ""))
  1108.        (string-match (car (car list)) elt)
  1109.        (setq rslt (car list)))
  1110.       (setq list (cdr list)))
  1111.     rslt))
  1112.  
  1113. (defun w3-goto-last-buffer ()
  1114.   "Go to last WWW buffer visited"
  1115.   (interactive)
  1116.   (if w3-current-last-buffer
  1117.       (if w3-frame-name
  1118.       (progn
  1119.         (delete-other-windows)
  1120.         (set-buffer w3-current-last-buffer)
  1121.         (w3-goto-last-buffer))
  1122.     (w3-notify-when-ready w3-current-last-buffer))
  1123.     (message "No previous buffer found.")))
  1124.  
  1125. (fset 'w3-replace-regexp 'url-replace-regexp)
  1126.  
  1127. ;;;###autoload
  1128. (defun w3-preview-this-buffer ()
  1129.   "See what this buffer will look like when its formatted as HTML.
  1130. HTML is the HyperText Markup Language used by the World Wide Web to
  1131. specify formatting for text.  More information on HTML can be found at
  1132. ftp.w3.org:/pub/www/doc."
  1133.   (interactive)
  1134.   (w3-fetch (concat "www://preview/" (buffer-name))))
  1135.  
  1136. (defun w3-source ()
  1137.   "Show the source of a file"
  1138.   (let ((tmp (buffer-name (generate-new-buffer "Document Source"))))
  1139.     (set-buffer url-working-buffer)
  1140.     (kill-buffer tmp)
  1141.     (rename-buffer tmp)
  1142.     ;; Make the URL show in list-buffers output
  1143.     (make-local-variable 'list-buffers-directory)
  1144.     (setq list-buffers-directory (url-view-url t))
  1145.     (set-buffer-modified-p nil)
  1146.     (buffer-enable-undo)
  1147.     (w3-notify-when-ready (get-buffer tmp))))
  1148.  
  1149. (defvar w3-mime-list-for-code-conversion
  1150.   '("text/plain" "text/html")
  1151.   "List of MIME types that require Mules' code conversion.")
  1152.  
  1153. (defun w3-convert-code-for-mule (mmtype)
  1154.   "Convert current data into the appropriate coding system"
  1155.   (and (or (not mmtype)
  1156.        (member mmtype w3-mime-list-for-code-conversion))
  1157.        (mule-code-convert-region
  1158.     (point-min) (point-max)
  1159.     (mule-detect-coding-version (point-min) (point-max)))))
  1160.  
  1161. (defun w3-sentinel (&optional proc string)
  1162.   (set-buffer url-working-buffer)
  1163.   (if (or (stringp proc)
  1164.       (bufferp proc)) (setq w3-current-last-buffer proc))
  1165.   (remove-hook 'after-change-functions 'url-after-change-function)
  1166.   (if url-be-asynchronous
  1167.       (progn
  1168.     (cond
  1169.      ((not (get-buffer url-working-buffer)) nil)
  1170.      ((url-mime-response-p) (url-parse-mime-headers)))
  1171.     (if (not url-current-mime-type)
  1172.         (setq url-current-mime-type (or (mm-extension-to-mime
  1173.                          (url-file-extension
  1174.                           (url-filename
  1175.                            url-current-object)))
  1176.                         "text/html")))))
  1177.   (if (not (string-match "^www:" (or (url-view-url t) "")))
  1178.       (w3-convert-code-for-mule url-current-mime-type))
  1179.       
  1180.   (let ((x (w3-build-continuation))
  1181.     (url (url-view-url t)))
  1182.     (while x
  1183.       (funcall (pop x)))))
  1184.  
  1185. (defun w3-show-history-list ()
  1186.   "Format the url-history-list prettily and show it to the user"
  1187.   (interactive)
  1188.   (w3-fetch "www://auto/history"))
  1189.  
  1190. (defun w3-save-as (&optional type)
  1191.   "Save a document to the local disk"
  1192.   (interactive)
  1193.   (save-excursion
  1194.     (let* ((completion-ignore-case t)
  1195.        (format (or type (completing-read
  1196.                  "Format: "
  1197.                  '(("HTML Source")
  1198.                    ("Formatted Text")
  1199.                    ("LaTeX Source")
  1200.                    ("PostScript")
  1201.                    ("Binary"))
  1202.                  nil t)))
  1203.        (fname (expand-file-name
  1204.            (read-file-name "File name: " default-directory)))
  1205.        (url (url-view-url t)))
  1206.       (cond
  1207.        ((equal "Binary" format)
  1208.     (if (not w3-current-source)
  1209.         (let ((url-be-asynchronous nil))
  1210.           (url-retrieve url))))
  1211.        ((equal "HTML Source" format)
  1212.     (if (not w3-current-source)
  1213.         (let ((url-be-asynchronous nil))
  1214.           (url-retrieve url))    ; Get the document if necessary
  1215.       (let ((txt w3-current-source))
  1216.         (set-buffer (get-buffer-create url-working-buffer))
  1217.         (erase-buffer)
  1218.         (insert txt)))
  1219.     (goto-char (point-min))
  1220.     (if (re-search-forward "<head>" nil t)
  1221.         (insert "\n"))
  1222.     (insert (format "<BASE HREF=\"%s\">\n" url)))
  1223.        ((or (equal "Formatted Text" format)
  1224.         (equal "" format))
  1225.     nil)                ; Do nothing - we have the text already
  1226.        ((equal "PostScript" format)
  1227.     (require 'ps-print)
  1228.     (let ((ps-spool-buffer-name " *w3-temp*"))
  1229.       (if (get-buffer ps-spool-buffer-name)
  1230.           (kill-buffer ps-spool-buffer-name))
  1231.       (ps-spool-buffer-with-faces)
  1232.       (set-buffer ps-spool-buffer-name)))
  1233.        ((equal "LaTeX Source" format)
  1234.     (w3-parse-tree-to-latex w3-current-parse url)))
  1235.       (write-region (point-min) (point-max) fname))))
  1236.  
  1237.  
  1238. ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
  1239. ;;; Functions to parse out <A> tags and replace it with a hyperlink zone
  1240. ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
  1241. (defun w3-popup-image-info (url)
  1242.   (interactive)
  1243.   (let* ((glyph (cdr-safe (assoc url w3-graphics-list)))
  1244.        image w h d info)
  1245.     (save-excursion
  1246.       (if (or (not glyph) (not (glyphp glyph)))
  1247.         (error "No information available."))
  1248.       (setq image (glyph-image-instance glyph))
  1249.       (if (or (not image) (not (image-instance-p image)))
  1250.         (error "No information available."))
  1251.       (setq w (glyph-width glyph)
  1252.           h (glyph-height glyph)
  1253.           d (image-instance-depth image)
  1254.           info (url-popup-info url)
  1255.           )
  1256.       (set-buffer (get-buffer-create "*Image Info*"))
  1257.       (erase-buffer)
  1258.       (insert
  1259.        "Information for: " url "\n"
  1260.        (make-string (1- (window-width)) ?-)
  1261.        (format "\n%-20s: %s\n" "Type" (image-instance-type image))
  1262.        (format "%-20s: %d x %d\n" "Dimensions" w h)
  1263.        (format "%-20s: %d-bit\n" "Color" d))
  1264.       (set-extent-begin-glyph (make-extent (point) (point)) glyph)
  1265.       (insert
  1266.        "\n"
  1267.        (make-string (1- (window-width)) ?-)
  1268.        (or info ""))
  1269.       (display-buffer (current-buffer) t))))
  1270.                
  1271. (defun w3-popup-info (&optional url)
  1272.   "Show information about the link under point. (All SGML attributes)"
  1273.   (interactive (list (or (w3-view-this-url t)
  1274.              (w3-read-url-with-default))))
  1275.   (let (dat widget)
  1276.     (if (interactive-p)
  1277.     nil
  1278.       (setq widget (widget-at (point))
  1279.         dat (and widget (widget-get widget 'attributes))))
  1280.     (if url
  1281.     (save-excursion
  1282.       (set-buffer (get-buffer-create "*Header Info*"))
  1283.       (erase-buffer)
  1284.       (insert "URL: " url "\n" (make-string (1- (window-width)) ?-) "\n")
  1285.       (if (and dat (listp dat))
  1286.           (insert
  1287.            "Link attributes:\n"
  1288.            (make-string (1- (window-width)) ?-) "\n"
  1289.            (mapconcat
  1290.         (function
  1291.          (lambda (info)
  1292.            (format "%20s :== %s" (car info) (or (cdr info) "On"))))
  1293.         dat "\n")
  1294.            "\n" (make-string (1- (window-width)) ?-) "\n"))
  1295.       (insert (save-excursion (url-popup-info url)))
  1296.       (goto-char (point-min))
  1297.       (display-buffer (current-buffer) t))
  1298.       (message "No URL to get information on!"))))
  1299.  
  1300. (fset 'w3-document-information-this-url 'w3-popup-info)
  1301.  
  1302.  
  1303. ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
  1304. ;;; Functions for logging of bad HTML
  1305. ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
  1306. (defun w3-reconstruct-tag (tagname desc)
  1307.   (concat "<" tagname " "
  1308.       (mapconcat
  1309.        (function (lambda (x)
  1310.                (if (cdr x)
  1311.                (concat (car x) "=\"" (cdr x) "\"")
  1312.              (car x)))) desc " ") ">"))
  1313.  
  1314. (defun w3-debug-if-found (regexp type desc)
  1315.   (and w3-debug-html
  1316.        (save-excursion
  1317.      (if (re-search-forward regexp nil t)
  1318.          (w3-log-bad-html type desc)))))
  1319.  
  1320. (defun w3-log-bad-html (type desc)
  1321.   ;; Log bad HTML to the buffer specified by w3-debug-buffer
  1322.   (if w3-debug-html
  1323.       (save-excursion
  1324.     (set-buffer (get-buffer-create w3-debug-buffer))
  1325.     (goto-char (point-max))
  1326.     (insert (make-string (1- (window-width)) w3-horizontal-rule-char) "\n")
  1327.     (cond
  1328.      ((stringp type) (insert type "\n" desc "\n"))
  1329.      ((eq type 'bad-quote)
  1330.       (insert "Unterminated quoting character in SGML attribute value.\n"
  1331.           desc "\n"))
  1332.      ((eq type 'no-quote)
  1333.       (insert "Unquoted SGML attribute value.\n" desc "\n"))
  1334.      ((eq type 'no-textarea-end)
  1335.       (insert "Unterminated <textarea> tag.\n"
  1336.           (w3-reconstruct-tag "textarea" desc) "\n"))
  1337.      ((eq type 'bad-link-tag)
  1338.       (insert "Must specify either REL or REV with a <link> tag.\n"
  1339.           (w3-reconstruct-tag "link" desc) "\n"))
  1340.      ((eq type 'no-a-end)
  1341.       (insert "Unterminated <a> tag.\n"
  1342.           (w3-reconstruct-tag "a" desc) "\n"))
  1343.      ((eq type 'no-form-end)
  1344.       (insert "Unterminated <form> tag.\n"
  1345.           (w3-reconstruct-tag "form" desc) "\n"))
  1346.      ((eq type 'bad-base-tag)
  1347.       (insert "Malformed <base> tag.\n"
  1348.           (w3-reconstruct-tag "base" desc) "\n"))))))
  1349.  
  1350.  
  1351. ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
  1352. ;;; Functions to handle formatting an html buffer
  1353. ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
  1354. (defun w3-add-delayed-graphic (widget)
  1355.   ;; Add a delayed image for the current buffer.
  1356.   (setq w3-delayed-images (cons widget w3-delayed-images)))
  1357.  
  1358.  
  1359. (defun w3-load-flavors ()
  1360.   ;; Load the correct emacsen specific stuff
  1361.   (cond
  1362.    ((and w3-running-xemacs (eq system-type 'ms-windows))
  1363.     (error "WinEmacs no longer supported."))
  1364.    (w3-running-xemacs (require 'w3-xemac))
  1365.    (t                    ; Assume we are the FSF variant
  1366.     (require (intern (format "w3-e%d" emacs-major-version)))))
  1367.   (if (featurep 'emacspeak)
  1368.       (condition-case ()
  1369.       (progn
  1370.         (require 'dtk-css-speech)
  1371.         (require 'w3-speak))))
  1372.   (condition-case ()
  1373.       (require 'w3-site-init)
  1374.     (error nil)))
  1375.  
  1376. ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
  1377. ;;; Automatic bug submission.                                               ;;;
  1378. ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
  1379. (defun w3-submit-bug ()
  1380.   "Submit a bug on Emacs-w3"
  1381.   (interactive)
  1382.   (require 'reporter)
  1383.   (and (yes-or-no-p "Do you really want to submit a bug on Emacs-w3? ")
  1384.        (let ((url (url-view-url t))
  1385.          (vars '(window-system
  1386.              window-system-version
  1387.              system-type
  1388.              ange-ftp-version
  1389.              url-gateway-method
  1390.              efs-version
  1391.              ange-ftp-version
  1392.              url-version
  1393.              url-be-asynchronous
  1394.              url)))
  1395.      (if (and url (string= url "file:nil")) (setq url nil))
  1396.      (mapcar
  1397.       (function
  1398.        (lambda (x)
  1399.          (if (not (and (boundp x) (symbol-value x)))
  1400.          (setq vars (delq x vars))))) vars)
  1401.      (reporter-submit-bug-report w3-bug-address
  1402.                      (concat "WWW v" w3-version-number " of "
  1403.                          w3-version-date)
  1404.                      vars
  1405.                      nil nil
  1406.                      "Description of Problem:"))))
  1407.  
  1408. (defalias 'w3-bug 'w3-submit-bug)
  1409.  
  1410. ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
  1411. ;;; Support for searching                            ;;;
  1412. ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
  1413. (defun w3-nuke-spaces-in-search (x)
  1414.   "Remove spaces from search strings . . ."
  1415.   (let ((new ""))
  1416.     (while (not (equal x ""))
  1417.       (setq new (concat new (if (= (string-to-char x) 32) "+"
  1418.                   (substring x 0 1)))
  1419.         x (substring x 1 nil)))
  1420.     new))
  1421.  
  1422. (defun w3-search ()
  1423.   "Perform a search, if this is a searchable index."
  1424.   (interactive)
  1425.   (let* (querystring            ; The string to send to the server
  1426.      (data
  1427.       (cond
  1428.        ((null w3-current-isindex)
  1429.         (let ((rels (cdr-safe (assq 'rel w3-current-links)))
  1430.           val cur)
  1431.           (while rels
  1432.         (setq cur (car rels)
  1433.               rels (cdr rels))
  1434.         (if (and (or (string-match "^isindex$" (car cur))
  1435.                  (string-match "^index$" (car cur)))
  1436.              (plist-get (cadr cur) 'href))
  1437.             (setq val (plist-get (cadr cur) 'href)
  1438.               rels nil))
  1439.         )
  1440.           (if val
  1441.           (cons val "Search on (+ separates keywords): "))))
  1442.        ((eq w3-current-isindex t)
  1443.         (cons (url-view-url t) "Search on (+ separates keywords): "))
  1444.        ((consp w3-current-isindex)
  1445.         w3-current-isindex)
  1446.        (t nil)))
  1447.      index)
  1448.     (if (null data) (error "Not a searchable index!"))
  1449.     (setq index (car data))
  1450.     (setq querystring (w3-nuke-spaces-in-search (read-string (cdr data))))
  1451.     (if (string-match "\\(.*\\)\\?.*" index)
  1452.     (setq index (url-match index 1)))
  1453.     (w3-fetch
  1454.      (concat index (if (= ?? (string-to-char (substring index -1 nil)))
  1455.                "" "?") querystring))))
  1456.  
  1457. ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
  1458. ;;; Auto documentation, etc                                                 ;;;
  1459. ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
  1460. (defun w3-help ()
  1461.   "Print documentation on w3 mode."
  1462.   (interactive)
  1463.   (w3-fetch "about:"))
  1464.  
  1465. ;;;###autoload
  1466. (defun w3-version (&optional here)
  1467.   "Show the version number of W3 in the minibuffer.
  1468. If optional argument HERE is non-nil, insert info at point."
  1469.   (interactive "P")
  1470.   (let ((version-string 
  1471.          (format "WWW %s, URL %s, MM %s" 
  1472.                  w3-version-number 
  1473.                  url-version
  1474.                  mm-version)))
  1475.     (if here 
  1476.         (insert version-string)
  1477.       (if (interactive-p)
  1478.           (message "%s" version-string)
  1479.         version-string))))
  1480.  
  1481. ;;;###autoload
  1482. (defun w3 ()
  1483.   "Retrieve the default World Wide Web home page.
  1484. The World Wide Web is a global hypertext system started by CERN in
  1485. Switzerland in 1991.
  1486.  
  1487. The home page is specified by the variable w3-default-homepage.  The
  1488. document should be specified by its fully specified Uniform Resource
  1489. Locator.  The document will be parsed as HTML (if appropriate) and
  1490. displayed in a new buffer."
  1491.   (interactive)
  1492.   (if (not w3-setup-done) (w3-do-setup))
  1493.   (if (and w3-track-last-buffer
  1494.        (bufferp w3-last-buffer)
  1495.        (buffer-name w3-last-buffer))
  1496.       (progn
  1497.     (switch-to-buffer w3-last-buffer)
  1498.     (message "Reusing buffer.  To reload, type %s."
  1499.          (substitute-command-keys "\\[w3-reload-document]")))
  1500.     (cond
  1501.      ((null w3-default-homepage) (call-interactively 'w3-fetch))
  1502.      ((not (stringp w3-default-homepage))
  1503.       (error "Invalid setting for w3-default-homepage: %S"
  1504.          w3-default-homepage))
  1505.      ((not (string-match ".*:.*" w3-default-homepage))
  1506.       (w3-fetch (concat "file:" w3-default-homepage)))
  1507.      (t
  1508.       (w3-fetch w3-default-homepage)))))
  1509.  
  1510. ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
  1511. ;;; Leftover stuff that didn't quite fit into url.el
  1512. ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
  1513.  
  1514. (defun w3-generate-error (type data)
  1515.   ;; Generate an HTML error buffer for error TYPE with data DATA.
  1516.   (setq url-current-mime-type "text/html")
  1517.   (cond
  1518.    ((equal type "nofile")
  1519.     (let ((error (save-excursion
  1520.           (set-buffer (get-buffer-create " *url-error*"))
  1521.           (buffer-string))))
  1522.       (if (string= "" error)
  1523.       (setq error
  1524.         (format (concat "The file %s could not be found.  "
  1525.                 "Either it does not exist, or it "
  1526.                 "is unreadable.") data)))
  1527.       (insert "<html>\n <head>\n"
  1528.         "  <title>Error</title>\n"
  1529.         " </head>\n <body>\n"
  1530.         "  <h1>Error accessing " data "</h1>\n"
  1531.         "  <hr>\n  <p>"
  1532.         error
  1533.         "\n  </p>\n")))
  1534.    ((equal type "nobuf")
  1535.     (insert "<title>Error</title>\n"
  1536.         "<H1>No buffer " data " found</h1>\n"
  1537.         "<HR>\n"
  1538.         "The buffer " data " could not be found.  It has either\n"
  1539.         "been killed or renamed.\n"))
  1540.    ((equal type "nohist")
  1541.     (insert "<TITLE>Error</TITLE>\n"
  1542.         "<H1>No history items found.</H1>\n"
  1543.         "<HR>\n"
  1544.         "There is no history list available at this time.  Either\n"
  1545.         "you have not visited any nodes, or the variable <i>\n"
  1546.         "url-keep-history</i> is nil.\n"))
  1547.    )
  1548.   (insert "<hr>\n"
  1549.       "If you feel this is a bug in Emacs-W3, <a href=\"mailto:"
  1550.       w3-bug-address "\">send mail to " w3-bug-address
  1551.       "</a>\n<hr>"))
  1552.  
  1553. (defun w3-generate-auto-html (type)
  1554.   ;; Generate one of several automatic html pages
  1555.   (setq url-current-mime-type "text/html"
  1556.     url-current-mime-headers '(("content-type" . "text/html")))
  1557.   (cond
  1558.    ((equal type "hotlist")
  1559.     (let ((tmp (reverse w3-hotlist)))
  1560.       (insert "<html>\n\t<head>\n\t\t"
  1561.           "<title> Hotlist </title>\n\t</head>\n"
  1562.           "\t<body>\n\t\t<div>\n\t\t\t<h1>Hotlist from " w3-hotlist-file
  1563.           "</h1>\n\t\t\t<ol>\n")
  1564.       (while tmp
  1565.     (insert  "\t\t\t\t<li> <a href=\"" (car (cdr (car tmp)))
  1566.          "\">" (url-insert-entities-in-string
  1567.             (car (car tmp))) "</a></li>\n")
  1568.     (setq tmp (cdr tmp)))
  1569.       (insert "\n\t\t\t</ol>\n\t\t</div>\n\t</body>\n</html>\n")))
  1570.    ((equal type "history")
  1571.     (if (not url-history-list)
  1572.     (url-retrieve "www://error/nohist")
  1573.       (insert "<html>\n\t<head>\n\t\t"
  1574.           "<title> History List For This Session of W3</title>"
  1575.           "\n\t</head>\n\t<body>\n\t\t<div>\n\t\t\t<h1>"
  1576.           "History List For This Session of W3</h1>\n\t\t\t<ol>\n")
  1577.       (cl-maphash
  1578.        (function
  1579.     (lambda (url desc)
  1580.       (insert (format "\t\t\t\t<li> <a href=\"%s\">%s</a>\n"
  1581.               url (url-insert-entities-in-string desc)))))
  1582.        url-history-list)
  1583.       (insert "\n\t\t\t</ol>\n\t\t</div>\n\t</body>\n</html>\n")))))
  1584.  
  1585. (defun w3-internal-handle-preview (buffer)
  1586.   (setq buffer (get-buffer buffer))
  1587.   (let ((base (get-text-property (point-min) 'w3-base buffer)))
  1588.     (if base
  1589.     (setq base (url-generic-parse-url base)))
  1590.     (insert-buffer buffer)
  1591.     (let ((inhibit-read-only t))
  1592.       (set-text-properties (point-min) (point-max) nil))
  1593.     (cond
  1594.      (base
  1595.       (setq url-current-object base))      
  1596.      ((buffer-file-name buffer)
  1597.       (setq url-current-object
  1598.         (url-generic-parse-url (concat "file:"
  1599.                        (buffer-file-name buffer)))))
  1600.      (t
  1601.       (setq url-current-object
  1602.         (url-generic-parse-url "file:/")
  1603.         url-current-mime-type "text/html")))))
  1604.  
  1605. (defun w3-internal-url (url)
  1606.   ;; Handle internal urls (previewed buffers, etc)
  1607.   (if (not (string-match "www:/+\\([^/]+\\)/\\(.*\\)" url))
  1608.       (w3-fetch "www://error/")
  1609.     (let ((type (url-match url 1))
  1610.       (data (url-match url 2)))
  1611.       (set-buffer (get-buffer-create url-working-buffer))
  1612.       (cond
  1613.        ((equal type "preview")        ; Previewing a document
  1614.     (if (get-buffer data)        ; Buffer still exists
  1615.         (w3-internal-handle-preview data)
  1616.       (url-retrieve (concat "www://error/nobuf/" data))))
  1617.        ((equal type "error")        ; Error message
  1618.     (if (string-match "\\([^/]+\\)/\\(.*\\)" data)
  1619.         (w3-generate-error (url-match data 1) (url-match data 2))
  1620.       (w3-generate-error data "")))
  1621.        ((equal type "auto")        ; Hotlist or help stuff
  1622.     (w3-generate-auto-html data))))))
  1623.  
  1624. ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
  1625. ;;; Stuff for good local file handling
  1626. ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
  1627. (defun w3-ff (file)
  1628.   "Find a file in any window already displaying it, otherwise just as
  1629. display-buffer, and using this function"
  1630.   (if (not (eq 'tty (device-type)))
  1631.       (let ((f (window-frame (display-buffer (find-file-noselect file)))))
  1632.     (set-mouse-position f 1 0)
  1633.     (raise-frame f)
  1634.     (unfocus-frame))
  1635.     (display-buffer (find-file-noselect file))))
  1636.  
  1637. (defun w3-default-local-file()
  1638.   "Use find-file to open the local file"
  1639.   (w3-ff (url-filename url-current-object)))
  1640.  
  1641. ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
  1642. ;;; Mode definition                                ;;;
  1643. ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
  1644. (defun w3-search-forward (string)
  1645.   (interactive "sSearch: ")
  1646.   (setq w3-last-search-item string)
  1647.   (if (and (not (search-forward string nil t))
  1648.        (funcall url-confirmation-func
  1649.             "End of document reached; continue from beginning? "))
  1650.       (progn
  1651.     (goto-char (point-min))
  1652.     (w3-search-forward string))))
  1653.  
  1654. (defun w3-search-again ()
  1655.   (interactive)
  1656.   (if (and w3-last-search-item
  1657.        (stringp w3-last-search-item))
  1658.       (if (and (not (search-forward w3-last-search-item nil t))
  1659.            (funcall url-confirmation-func
  1660.             "End of document reached; continue from beginning? "))
  1661.       (progn
  1662.         (goto-char (point-min))
  1663.         (w3-search-again)))))
  1664.  
  1665. (defun w3-find-specific-link (link)
  1666.   (let ((pos (assq (intern link) w3-id-positions)))
  1667.     (if pos
  1668.     (progn
  1669.       (goto-char (cdr pos))
  1670.       (if (and (eolp) (not (eobp)))
  1671.           (forward-char 1)))
  1672.       (message "Link #%s not found." link))))
  1673.  
  1674. (defun w3-force-reload-document ()
  1675.   "Reload the current document.  Take it from the network, even if
  1676. cached and in local mode."
  1677.   (let ((url-standalone-mode nil))
  1678.     (w3-reload-document)))
  1679.  
  1680. (defun w3-reload-document ()
  1681.   "Reload the current document"
  1682.   (interactive)
  1683.   (let ((tmp (url-view-url t))
  1684.     (pnt (point))
  1685.     (window-start (progn
  1686.             (move-to-window-line 0)
  1687.             (point)))
  1688.     (url-request-extra-headers '(("Pragma" . "no-cache"))))
  1689.     (kill-buffer (current-buffer))
  1690.     (w3-fetch tmp)
  1691.     (goto-char pnt)
  1692.     (set-window-start (selected-window) (min window-start (point-max)))))
  1693.  
  1694. (defun w3-leave-buffer ()
  1695.   "Bury this buffer, but don't kill it."
  1696.   (interactive)
  1697.   (let ((x w3-current-last-buffer))
  1698.     (if w3-frame-name
  1699.     (w3-leave-or-quit-frameset x nil)
  1700.       (progn
  1701.     (bury-buffer nil)
  1702.     (if (and (bufferp x) (buffer-name x))
  1703.         (w3-notify-when-ready x))))))
  1704.  
  1705. (defun w3-quit (&optional mega)
  1706.   "Quit WWW mode"
  1707.   (interactive "P")
  1708.   (if mega
  1709.       (mapcar
  1710.        (function
  1711.     (lambda (x)
  1712.       (save-excursion
  1713.         (set-buffer (get-buffer x))
  1714.         (if (eq major-mode 'w3-mode)
  1715.         (w3-quit nil)))))
  1716.        (buffer-list))
  1717.     (let ((x w3-current-last-buffer))
  1718.       (if w3-frame-name
  1719.       (w3-leave-or-quit-frameset x t)
  1720.     (progn
  1721.       (kill-buffer (current-buffer))
  1722.       (if (and (bufferp x) (buffer-name x))
  1723.           (w3-notify-when-ready x)))))))
  1724.  
  1725. (defun w3-leave-or-quit-frameset (x quit-p &optional top-down-p)
  1726.   (set-buffer x)
  1727.   (delete-other-windows)
  1728.   (let ((structure (reverse w3-frameset-structure)))
  1729.     (while structure
  1730.       (let ((elt (car structure)))
  1731.     (if (eq (car elt) 'frame)
  1732.         (let* ((url (nth 2 elt))
  1733.            (buf (url-buffer-visiting url)))
  1734.           (if buf
  1735.           (progn
  1736.             (set-buffer buf)
  1737.             (if w3-frameset-structure
  1738.             (w3-leave-or-quit-frameset buf quit-p t)
  1739.               (if quit-p
  1740.               (kill-buffer buf)
  1741.             (bury-buffer buf))))))))
  1742.       (pop structure)))
  1743.   (if top-down-p
  1744.       (if quit-p
  1745.       (kill-buffer x)
  1746.     (bury-buffer x))
  1747.     (progn
  1748.       (set-buffer x)
  1749.       (if quit-p
  1750.       (w3-quit nil)
  1751.     (w3-leave-buffer)))))
  1752.  
  1753. (defun w3-view-this-url (&optional no-show)
  1754.   "View the URL of the link under point"
  1755.   (interactive)
  1756.   (let* ((widget (widget-at (point)))
  1757.      (parent (and widget (widget-get widget :parent)))
  1758.      (href (or (and widget (widget-get widget :href))
  1759.            (and parent (widget-get parent :href)))))
  1760.     (cond
  1761.      ((and no-show href)
  1762.       href)
  1763.      (href
  1764.       (message "%s" (url-truncate-url-for-viewing href)))
  1765.      (no-show
  1766.       nil)
  1767.      (widget
  1768.       (widget-echo-help (point)))
  1769.      (t
  1770.       nil))))
  1771.  
  1772. (defun w3-load-delayed-images ()
  1773.     "Load inlined images that were delayed, if any."
  1774.   (interactive)
  1775.   (let ((w3-delay-image-loads nil)
  1776.     (todo w3-delayed-images))
  1777.     (setq w3-delayed-images nil)
  1778.     (while todo
  1779.       (w3-maybe-start-image-download (car todo))
  1780.       (setq todo (cdr todo)))))
  1781.  
  1782. (defun w3-save-this-url ()
  1783.   "Save url under point in the kill ring"
  1784.   (interactive)
  1785.   (w3-save-url t))
  1786.  
  1787. (defun w3-save-url (under-pt)
  1788.   "Save current url in the kill ring"
  1789.   (interactive "P")
  1790.   (let ((x (cond
  1791.         ((stringp under-pt) under-pt)
  1792.         (under-pt (w3-view-this-url t))
  1793.         (t (url-view-url t)))))
  1794.     (if x
  1795.     (progn
  1796.       (setq kill-ring (cons x kill-ring))
  1797.       (setq kill-ring-yank-pointer kill-ring)
  1798.       (message "Stored URL in kill-ring.")
  1799.       (if (fboundp 'w3-store-in-clipboard)
  1800.           (w3-store-in-clipboard x)))
  1801.       (error "No URL to store."))))
  1802.  
  1803. (fset 'w3-end-of-document 'end-of-buffer)
  1804. (fset 'w3-start-of-document 'beginning-of-buffer)
  1805.  
  1806. (defun w3-scroll-up (&optional lines)
  1807.   "Scroll forward in View mode, or exit if end of text is visible.
  1808. No arg means whole window full.  Arg is number of lines to scroll."
  1809.   (interactive "P")
  1810.   (if (and (pos-visible-in-window-p (point-max))
  1811.        ;; Allow scrolling backward at the end of the buffer.
  1812.        (or (null lines)
  1813.            (> lines 0)))
  1814.       nil
  1815.     (let ((view-lines (1- (window-height))))
  1816.       (setq lines
  1817.         (if lines (prefix-numeric-value lines)
  1818.           view-lines))
  1819.       (if (>= lines view-lines)
  1820.       (scroll-up nil)
  1821.     (if (>= (- lines) view-lines)
  1822.         (scroll-down nil)
  1823.       (scroll-up lines)))
  1824.       (cond ((pos-visible-in-window-p (point-max))
  1825.          (goto-char (point-max))
  1826.          (recenter -1)))
  1827.       (move-to-window-line -1)
  1828.       (beginning-of-line))))
  1829.  
  1830. (defun w3-mail-document-author ()
  1831.   "Send mail to the author of this document, if possible."
  1832.   (interactive)
  1833.   (let ((x w3-current-links)
  1834.     (y nil)
  1835.     (found nil))
  1836.     (setq found (cdr-safe (assoc "reply-to" url-current-mime-headers)))
  1837.     (if (and found (not (string-match url-nonrelative-link found)))
  1838.     (setq found (list (concat "mailto:" found))))
  1839.     (while (and x (not found))
  1840.       (setq y (car x)
  1841.         x (cdr x)
  1842.         found (cdr-safe (assoc "made" y))))
  1843.     (if found
  1844.     (let ((possible nil)
  1845.           (href nil))
  1846.       (setq x (car found))        ; Fallback if no mail(to|server) found
  1847.       (while found
  1848.         (setq href (plist-get (pop found) 'href))
  1849.         (if (and href (string-match "^mail[^:]+:" href))
  1850.         (setq possible (cons href possible))))
  1851.       (case (length possible)
  1852.         (0                ; No mailto links found
  1853.          (w3-fetch x))        ; fall back onto first 'made' link
  1854.         (1                ; Only one found, get it
  1855.          (w3-fetch (car possible)))
  1856.         (otherwise
  1857.          (w3-fetch (completing-read "Choose an address: "
  1858.                     (mapcar 'list possible)
  1859.                     nil t (car possible))))))
  1860.       (message "Could not automatically determine authors address, sorry."))))
  1861.  
  1862. (defun w3-kill-emacs-func ()
  1863.   "Routine called when exiting emacs.  Do miscellaneous clean up."
  1864.   (and (eq url-keep-history t)
  1865.        url-global-history-hash-table
  1866.        (url-write-global-history))
  1867.   (message "Cleaning up w3 storage...")
  1868.   (let ((x (nconc
  1869.         (and (file-exists-p w3-temporary-directory)
  1870.          (directory-files w3-temporary-directory t "url-tmp.*"))
  1871.         (and (file-exists-p url-temporary-directory)
  1872.          (directory-files url-temporary-directory t
  1873.                   (concat "url"
  1874.                       (int-to-string
  1875.                        (user-real-uid)) ".*")))
  1876.         (and (file-exists-p url-temporary-directory)
  1877.          (directory-files url-temporary-directory t "url-tmp.*")))))
  1878.     (while x
  1879.       (condition-case ()
  1880.       (delete-file (car x))
  1881.     (error nil))
  1882.       (setq x (cdr x))))
  1883.   (message "Cleaning up w3 storage... done."))
  1884.  
  1885. (cond
  1886.  ((fboundp 'display-warning)
  1887.   (fset 'w3-warn 'display-warning))
  1888.  ((fboundp 'warn)
  1889.   (defun w3-warn (class message &optional level)
  1890.     (if (and (eq class 'html)
  1891.          (not w3-debug-html))
  1892.     nil
  1893.       (warn "(%s/%s) %s" class (or level 'warning) message))))
  1894.  (t
  1895.   (defun w3-warn (class message &optional level)
  1896.     (if (and (eq class 'html)
  1897.          (not w3-debug-html))
  1898.     nil
  1899.       (save-excursion
  1900.     (set-buffer (get-buffer-create "*W3-WARNINGS*"))
  1901.     (goto-char (point-max))
  1902.     (save-excursion
  1903.       (insert (format "(%s/%s) %s\n" class (or level 'warning) message)))
  1904.     (display-buffer (current-buffer)))))))
  1905.  
  1906. (defun w3-internal-expander (urlobj defobj)
  1907.   ;; URL Expansion routine for internally handled routines
  1908.   (url-identity-expander urlobj defobj))
  1909.  
  1910. (defun w3-map-links (function &optional buffer from to maparg)
  1911.   "Map FUNCTION over the hypertext links which overlap region in BUFFER,
  1912. starting at FROM and ending at TO.  FUNCTION is called with the arguments
  1913. WIDGET and MAPARG.
  1914. The arguments FROM, TO, MAPARG, and BUFFER default to the beginning of
  1915. BUFFER, the end of BUFFER, nil, and (current-buffer), respectively."
  1916.   (let ((parent)
  1917.     (highly-unlikely-name-for-a-variable-holding-a-function function))
  1918.     (widget-map-buttons
  1919.      (function
  1920.       (lambda (widget arg)
  1921.     (setq parent (and widget (widget-get widget :parent)))
  1922.     ;; Check to see if its got a URL tacked on it somewhere
  1923.     (cond
  1924.      ((and widget (widget-get widget :href))
  1925.       (funcall highly-unlikely-name-for-a-variable-holding-a-function
  1926.            widget maparg))
  1927.      ((and parent (widget-get parent :href))
  1928.       (funcall highly-unlikely-name-for-a-variable-holding-a-function
  1929.            widget maparg))
  1930.      (t nil))
  1931.     nil)))))
  1932.  
  1933. (defun w3-emit-image-warnings-if-necessary ()
  1934.   (if (and (not w3-delay-image-loads)
  1935.        (fboundp 'w3-insert-graphic)
  1936.        (or (not (featurep 'gif))
  1937.            (not (featurep 'jpeg)))
  1938.        (not (w3-executable-exists-in-path "ppmtoxpm"))
  1939.        (not (or
  1940.          (w3-executable-exists-in-path "pbmtoxbm")
  1941.          (w3-executable-exists-in-path "ppmtoxbm"))))
  1942.       (w3-warn
  1943.        'image
  1944.        (concat
  1945.     "Could not find some vital ppm utilities in exec-path.\n"
  1946.     "This probably means that you will be unable to view any\n"
  1947.     "inlined images other than: "
  1948.     (mapconcat
  1949.      (function
  1950.       (lambda (x)
  1951.         (if (featurep x) (concat (symbol-name x) ",\n"))))
  1952.      '(png jpg gif xpm xbm) "")
  1953.     "\n\n"
  1954.     "If you do not have the PPM utilities from either the PBMPLUS\n"
  1955.     "or NETPBM distributions installed on your machine, then\n"
  1956.     "please set the variable `w3-delay-image-loads' to t with a\n"
  1957.     "line like:\n\n"
  1958.     "\t(setq w3-delay-image-loads t)\n\n"
  1959.     "in your ~/.emacs file.\n\n"
  1960.     "You can find the NETPBM utilities in:\n"
  1961.     "\tftp://ftp.cs.indiana.edu/pub/elisp/w3/images/\n"
  1962.     ))))
  1963.  
  1964. (defun w3-refresh-stylesheets ()
  1965.   "Reload all stylesheets."
  1966.   (interactive)
  1967.   (setq w3-user-stylesheet nil
  1968.     w3-face-cache nil)
  1969.   (w3-find-default-stylesheets)
  1970.   )
  1971.  
  1972. (defvar w3-loaded-stylesheets nil
  1973.   "A list of all the stylesheets Emacs-W3 loaded at startup.")
  1974.  
  1975. (defun w3-find-default-stylesheets ()
  1976.   (setq w3-loaded-stylesheets nil)
  1977.   (let* ((lightp (css-color-light-p 'default))
  1978.      (longname (if lightp "stylesheet-light" "stylesheet-dark"))
  1979.      (shortname (if lightp "light.css" "dark.css"))
  1980.      (w3-lisp (file-name-directory (locate-library "w3")))
  1981.      (w3-root (expand-file-name "../.." w3-lisp))
  1982.      (no-user-init (= 0 (length user-init-file)))
  1983.      (w3-configuration-directory (if no-user-init
  1984.                      "/this/is/a/highly/unlikely/directory/name"
  1985.                        w3-configuration-directory))
  1986.      (directories (list
  1987.                (if (fboundp 'locate-data-directory)
  1988.                (locate-data-directory "w3"))
  1989.                data-directory
  1990.                (concat data-directory "w3/")
  1991.                (expand-file-name "../../w3" data-directory)
  1992.                w3-lisp
  1993.                w3-root
  1994.                (expand-file-name "w3" w3-root)
  1995.                (expand-file-name "etc" w3-root)
  1996.                (expand-file-name "etc/w3" w3-root)
  1997.                 (expand-file-name "../" w3-lisp)
  1998.                 (expand-file-name "../w3" w3-lisp)
  1999.                 (expand-file-name "../etc" w3-lisp)
  2000.                w3-configuration-directory))
  2001.      (total-found 0)
  2002.      (possible (append
  2003.             (apply
  2004.              'append
  2005.              (mapcar
  2006.               (function
  2007.                (lambda (dir)
  2008.              (list
  2009.               (expand-file-name shortname dir)
  2010.               (expand-file-name longname dir)
  2011.               (expand-file-name "stylesheet" dir)
  2012.               (expand-file-name "default.css" dir))))
  2013.               directories))
  2014.             (and (not no-user-init)
  2015.              (list w3-default-stylesheet))))
  2016.      (remember possible)
  2017.      (old-asynch (default-value 'url-be-asynchronous))
  2018.      (found nil)
  2019.      (cur nil)
  2020.      (url nil))
  2021.     (unwind-protect
  2022.     (progn
  2023.       (setq-default url-be-asynchronous nil)
  2024.       (while possible
  2025.         (setq cur (car possible)
  2026.           possible (cdr possible)
  2027.           found (and cur (file-exists-p cur) (file-readable-p cur)
  2028.                  (not (file-directory-p cur)) cur))
  2029.         (if found
  2030.         (setq total-found (1+ total-found)
  2031.               w3-loaded-stylesheets (cons cur w3-loaded-stylesheets)
  2032.               w3-user-stylesheet (css-parse (concat "file:" cur) nil
  2033.                             w3-user-stylesheet)))))
  2034.       (setq-default url-be-asynchronous old-asynch))
  2035.     (if (= 0 total-found)
  2036.     (progn
  2037.       (w3-warn
  2038.        'style
  2039.        (concat
  2040.         "No stylesheets found!  Check configuration! DANGER DANGER!\n"
  2041.         "Emacs-W3 checked for its stylesheet in the following places\n"
  2042.         "and did not find one.  This means that some formatting will\n"
  2043.         "be wrong, and most colors and fonts will not be set up correctly.\n"
  2044.         "------\n"
  2045.         (mapconcat 'identity remember "\n")
  2046.         "------"))
  2047.       (error "No stylesheets found!  Check configuration! DANGER DANGER!")))))
  2048.  
  2049. (defvar w3-widget-global-map nil)
  2050.  
  2051. ;;;###autoload
  2052. (defun w3-do-setup ()
  2053.   "Do setup - this is to avoid conflict with user settings when W3 is
  2054. dumped with emacs."
  2055.   (url-do-setup)
  2056.   (url-register-protocol 'about 'w3-about 'url-identity-expander)
  2057.   (url-register-protocol 'www 'w3-internal-url 'w3-internal-expander)
  2058.   (w3-load-flavors)
  2059.   (w3-setup-version-specifics)
  2060.   (setq w3-default-configuration-file (expand-file-name 
  2061.                        (or w3-default-configuration-file
  2062.                        "profile")
  2063.                        w3-configuration-directory))
  2064.   (if (and init-file-user
  2065.        w3-default-configuration-file
  2066.        (file-exists-p w3-default-configuration-file))
  2067.       (condition-case e
  2068.       (load w3-default-configuration-file nil t)
  2069.     (error
  2070.      (let ((buf-name " *Configuration Error*"))
  2071.        (if (get-buffer buf-name)
  2072.            (kill-buffer (get-buffer buf-name)))
  2073.        (display-error e (get-buffer-create buf-name))
  2074.        (save-excursion
  2075.          (switch-to-buffer-other-window buf-name)
  2076.          (shrink-window-if-larger-than-buffer))
  2077.        (w3-warn 'configuration
  2078.             (format (eval-when-compile
  2079.                   (concat
  2080.                    "Configuration file `%s' contains an error.\n"
  2081.                    "Please consult the `%s' buffer for details."))
  2082.                 w3-default-configuration-file buf-name))))))
  2083.            
  2084.   (if (and (eq w3-user-colors-take-precedence 'guess)
  2085.        (not (eq (device-type) 'tty))
  2086.        (not (eq (device-class) 'mono)))
  2087.       (progn
  2088.     (setq w3-user-colors-take-precedence t)
  2089.     (w3-warn
  2090.      'html
  2091.      "Disabled document color specification because of mono display.")))
  2092.  
  2093.   (w3-refresh-stylesheets)
  2094.   (setq w3-setup-done t)
  2095.   (if (not url-global-history-file)
  2096.       (setq url-global-history-file
  2097.         (expand-file-name "history"
  2098.                   w3-configuration-directory)))
  2099.  
  2100.   (add-minor-mode 'w3-netscape-emulation-minor-mode " NS"
  2101.           w3-netscape-emulation-minor-mode-map)
  2102.   (add-minor-mode 'w3-lynx-emulation-minor-mode " Lynx"
  2103.           w3-lynx-emulation-minor-mode-map)
  2104.   
  2105.   (setq url-package-version w3-version-number
  2106.     url-package-name "Emacs-W3")
  2107.  
  2108.   (w3-setup-terminal-chars)
  2109.  
  2110.   (w3-emit-image-warnings-if-necessary)
  2111.            
  2112.   (cond
  2113.    ((memq system-type '(ms-dos ms-windows))
  2114.     (setq w3-hotlist-file (or w3-hotlist-file
  2115.                   (expand-file-name "~/mosaic.hot"))
  2116.       ))
  2117.    ((memq system-type '(axp-vms vax-vms))
  2118.     (setq w3-hotlist-file (or w3-hotlist-file
  2119.                   (expand-file-name "~/mosaic.hotlist-default"))
  2120.       ))
  2121.    (t 
  2122.     (setq w3-hotlist-file (or w3-hotlist-file
  2123.                   (expand-file-name "~/.mosaic-hotlist-default"))
  2124.       )))
  2125.   
  2126.   ; Set up a hook that will save the history list when
  2127.   ; exiting emacs
  2128.   (add-hook 'kill-emacs-hook 'w3-kill-emacs-func)
  2129.  
  2130.   (mm-parse-mailcaps)
  2131.   (mm-parse-mimetypes)
  2132.  
  2133.   ; Load in the hotlist if they haven't set it already
  2134.   (or w3-hotlist (w3-parse-hotlist))
  2135.  
  2136.   ; Set the default home page, honoring their defaults, then
  2137.   ; the standard WWW_HOME, then default to the documentation @ IU
  2138.   (or w3-default-homepage
  2139.       (setq w3-default-homepage
  2140.         (or (getenv "WWW_HOME")
  2141.         "http://www.cs.indiana.edu/elisp/w3/docs.html")))
  2142.  
  2143.   (run-hooks 'w3-load-hook))
  2144.  
  2145. (defun w3-mark-link-as-followed (ext dat)
  2146.   ;; Mark a link as followed
  2147.   (message "Reimplement w3-mark-link-as-followed"))
  2148.  
  2149. (defun w3-only-links ()
  2150.   (let* (result temp)
  2151.     (w3-map-links (function
  2152.            (lambda (x y)
  2153.              (setq result (cons x result)))))
  2154.     result))
  2155.  
  2156. (defun w3-download-callback (fname buff)
  2157.   (if (and (get-buffer buff) (buffer-name buff))
  2158.       (save-excursion
  2159.     (set-buffer buff)
  2160.     (let ((require-final-newline nil)
  2161.           (file-name-handler-alist nil)
  2162.           (write-file-hooks nil)
  2163.           (write-contents-hooks nil)
  2164.           (enable-multibyte-characters t) ; mule 2.4
  2165.           (buffer-file-coding-system mule-no-coding-system) ; mule 2.4
  2166.           (file-coding-system mule-no-coding-system) ; mule 2.3
  2167.           (mc-flag t))        ; mule 2.3
  2168.       (write-file fname)
  2169.       (message "Download of %s complete." (url-view-url t))
  2170.       (sit-for 3)
  2171.       (kill-buffer buff)))))
  2172.  
  2173. (defun w3-download-url-at-point ()
  2174.   "Download the URL under point."
  2175.   (interactive)
  2176.   (w3-download-url-wrapper t))
  2177.  
  2178. (defun w3-download-this-url ()
  2179.   "Download the current URL."
  2180.   (interactive)
  2181.   (w3-download-url-wrapper nil))
  2182.   
  2183. (defun w3-download-url-wrapper (under-pt)
  2184.   "Download current URL."
  2185.   (let ((x (if under-pt (w3-view-this-url t) (url-view-url t))))
  2186.     (if x
  2187.     (w3-download-url x)
  2188.       (error "No link found."))))
  2189.          
  2190. (defun w3-download-url (url &optional file-name)
  2191.   (interactive (list (w3-read-url-with-default)))
  2192.   (let* ((old-asynch (default-value 'url-be-asynchronous))
  2193.      (url-inhibit-uncompression t)
  2194.      (url-mime-accept-string "*/*")
  2195.      (urlobj (url-generic-parse-url url))
  2196.      (url-working-buffer
  2197.       (generate-new-buffer (concat " *" url " download*")))
  2198.      (stub-fname (url-basepath (or (url-filename urlobj) "") t))
  2199.      (dir (or mm-download-directory "~/"))
  2200.      (fname (or file-name
  2201.             (expand-file-name
  2202.              (read-file-name "Filename to save as: "
  2203.                      dir
  2204.                      stub-fname
  2205.                      nil
  2206.                      stub-fname) dir))))
  2207.     (unwind-protect
  2208.     (progn
  2209.       (or file-name
  2210.           (setq-default url-be-asynchronous t))
  2211.       (save-excursion
  2212.         (set-buffer url-working-buffer)
  2213.         (or file-name
  2214.         (setq url-current-callback-data (list fname (current-buffer))
  2215.               url-be-asynchronous t
  2216.               url-current-callback-func 'w3-download-callback))
  2217.         (url-retrieve url)
  2218.         (and file-name
  2219.          (w3-download-callback fname (current-buffer) t))))
  2220.       (or file-name
  2221.       (setq-default url-be-asynchronous old-asynch)))))
  2222.  
  2223. ;;;###autoload
  2224. (defun w3-follow-link-other-frame (&optional p)
  2225.   "Attempt to follow the hypertext reference under point in a new frame.
  2226. With prefix-arg P, ignore viewers and dump the link straight
  2227. to disk."
  2228.   (cond
  2229.    ((and (fboundp 'make-frame)
  2230.      (fboundp 'select-frame))
  2231.     (let ((frm (make-frame)))
  2232.       (select-frame frm)
  2233.       (w3-follow-link p)))
  2234.    (t (w3-follow-link p))))
  2235.  
  2236. ;;;###autoload
  2237. (defun w3-follow-link (&optional p)
  2238.   "Attempt to follow the hypertext reference under point.
  2239. With prefix-arg P, ignore viewers and dump the link straight
  2240. to disk."
  2241.   (interactive "P")
  2242.   (let* ((widget (widget-at (point)))
  2243.      (href (and widget (widget-get widget :href))))
  2244.     (cond
  2245.      ((null href) nil)
  2246.      ((or p w3-dump-to-disk)
  2247.       (w3-download-url href))
  2248.      (t
  2249.       (w3-fetch href)))))
  2250.  
  2251. (defun w3-widget-forward (arg)
  2252.   "Move point to the next field or button.
  2253. With optional ARG, move across that many fields."
  2254.   (interactive "p")
  2255.   (widget-forward arg))
  2256.  
  2257. (defun w3-widget-backward (arg)
  2258.   "Move point to the previous field or button.
  2259. With optional ARG, move across that many fields."
  2260.   (interactive "p")
  2261.   (w3-widget-forward (- arg)))
  2262.  
  2263. (defun w3-complete-link ()
  2264.   "Choose a link from the current buffer and follow it"
  2265.   (interactive)
  2266.   (let (links-alist
  2267.     link-at-point
  2268.     choice
  2269.     (completion-ignore-case t))
  2270.     (setq link-at-point (widget-at (point))
  2271.       link-at-point (and
  2272.              link-at-point
  2273.              (widget-get link-at-point :href)
  2274.              (widget-get link-at-point :from)
  2275.              (widget-get link-at-point :to)
  2276.              (w3-fix-spaces
  2277.               (buffer-substring-no-properties
  2278.                (widget-get link-at-point :from)
  2279.                (widget-get link-at-point :to)))))
  2280.     (w3-map-links (function
  2281.            (lambda (widget arg)
  2282.              (if (and (widget-get widget :from)
  2283.                   (widget-get widget :to))
  2284.              (setq links-alist (cons
  2285.                         (cons
  2286.                          (w3-fix-spaces
  2287.                           (buffer-substring-no-properties
  2288.                            (widget-get widget :from)
  2289.                            (widget-get widget :to)))
  2290.                          (widget-get widget :href))
  2291.                         links-alist))))))
  2292.     (if (not links-alist) (error "No links in current document."))
  2293.     (setq links-alist (sort links-alist (function
  2294.                      (lambda (x y)
  2295.                        (string< (car x) (car y))))))
  2296.     ;; Destructively remove duplicate entries from links-alist.
  2297.     (let ((remaining-links links-alist))
  2298.       (while remaining-links
  2299.     (if (equal (car remaining-links) (car (cdr remaining-links)))
  2300.         (setcdr remaining-links (cdr (cdr remaining-links)))
  2301.       (setq remaining-links (cdr remaining-links)))))
  2302.     (setq choice (completing-read
  2303.           (if link-at-point
  2304.               (concat "Link (default "
  2305.                   (if (< (length link-at-point) 20)
  2306.                   link-at-point
  2307.                 (concat
  2308.                  (substring link-at-point 0 17) "..."))
  2309.                   "): ")
  2310.             "Link: ") links-alist nil t))
  2311.     (if (and (string= choice "") link-at-point)
  2312.     (setq choice link-at-point))
  2313.     (let ((match (try-completion choice links-alist)))
  2314.       (cond
  2315.        ((eq t match)            ; We have an exact match
  2316.     (setq choice (cdr (assoc choice links-alist))))
  2317.        ((stringp match)
  2318.     (setq choice (cdr (assoc match links-alist))))
  2319.        (t (setq choice nil)))
  2320.       (if choice
  2321.       (w3-fetch choice)))))
  2322.  
  2323. (defun w3-display-errors ()
  2324.   "Display any HTML errors for the current page."
  2325.   (interactive)
  2326.   (let ((w3-notify 'friendly)
  2327.     (inhibit-read-only t)
  2328.     (buffer nil)
  2329.     (todo w3-current-badhtml)
  2330.     (url (url-view-url t)))
  2331.     (if (not todo)
  2332.     (error "No HTML errors on this page!  Amazing, isn't it?"))
  2333.     (save-excursion
  2334.       (set-buffer
  2335.        (get-buffer-create (concat "HTML Errors for: " (or url "???"))))
  2336.       (setq buffer (current-buffer))
  2337.       (erase-buffer)
  2338.       (while todo
  2339.     (goto-char (point-min))
  2340.     (insert "\n" (car todo))
  2341.     (setq todo (cdr todo)))
  2342.       (if url
  2343.       (progn
  2344.         (goto-char (point-min))
  2345.         (insert (format "HTML Errors for: <URL:%s>\n" url))))
  2346.       (set (make-local-variable 'font-lock-keywords) w3-html-errors-font-lock-keywords)
  2347.       (set (make-local-variable 'font-lock-keywords-only) nil)
  2348.       (set (make-local-variable 'font-lock-keywords-case-fold-search) nil)
  2349.       (set (make-local-variable 'font-lock-syntax-table) nil)
  2350.       (set (make-local-variable 'font-lock-beginning-of-syntax-function) 'beginning-of-line)
  2351.       (run-hooks 'w3-display-errors-hook))
  2352.     (w3-notify-when-ready buffer)))
  2353.  
  2354. (defun w3-mode ()
  2355.   "Mode for viewing HTML documents.  If called interactively, will
  2356. display the current buffer as HTML.
  2357.  
  2358. Current keymap is:
  2359. \\{w3-mode-map}"
  2360.   (interactive)
  2361.   (or w3-setup-done (w3-do-setup))
  2362.   (if (interactive-p)
  2363.       (w3-preview-this-buffer)
  2364.     (let ((tmp (mapcar (function (lambda (x) (cons x (symbol-value x))))
  2365.                w3-persistent-variables)))
  2366.       ;; Oh gross, this kills buffer-local faces in XEmacs
  2367.       ;;(kill-all-local-variables)
  2368.       (use-local-map w3-mode-map)
  2369.       (setq mode-name "WWW")
  2370.       (mapcar (function (lambda (x) (set-variable (car x) (cdr x)))) tmp)
  2371.       (setq major-mode 'w3-mode)
  2372.       (w3-mode-version-specifics)
  2373.       (w3-menu-install-menus)
  2374.       (setq url-current-passwd-count 0
  2375.         truncate-lines t
  2376.         mode-line-format w3-modeline-format)
  2377.       (run-hooks 'w3-mode-hook)
  2378.       (widget-setup))))
  2379.  
  2380. (require 'mm)
  2381. (require 'url)
  2382. (require 'w3-parse)
  2383. (require 'w3-display)
  2384. (require 'w3-auto)
  2385. (require 'w3-emulate)
  2386. (require 'w3-menu)
  2387. (require 'w3-mouse)
  2388. (provide 'w3)
  2389.